Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TFunction.cxx
Go to the documentation of this file.
1 // @(#)root/meta:$Id$
2 // Author: Fons Rademakers 07/02/97
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TFunction
13 Global functions class (global functions are obtained from CINT).
14 This class describes one single global function.
15 The TROOT class contains a list of all currently defined global
16 functions (accessible via TROOT::GetListOfGlobalFunctions()).
17 */
18 
19 #include "TFunction.h"
20 #include "TMethodArg.h"
21 #include "TROOT.h"
22 #include "TInterpreter.h"
23 #include "Strlen.h"
24 
25 #include <iostream>
26 #include "TVirtualMutex.h"
27 
28 ClassImp(TFunction);
29 
30 ////////////////////////////////////////////////////////////////////////////////
31 /// Default TFunction ctor. TFunctions are constructed in TROOT via
32 /// a call to TCling::UpdateListOfGlobalFunctions().
33 
34 TFunction::TFunction(MethodInfo_t *info) : TDictionary()
35 {
36  fInfo = info;
37  fMethodArgs = 0;
38  if (fInfo) {
39  SetName(gCling->MethodInfo_Name(fInfo));
40  SetTitle(gCling->MethodInfo_Title(fInfo));
41  fMangledName = gCling->MethodInfo_GetMangledName(fInfo);
42  }
43 }
44 
45 ////////////////////////////////////////////////////////////////////////////////
46 /// Copy operator.
47 
48 TFunction::TFunction(const TFunction &orig) : TDictionary(orig)
49 {
50  if (orig.fInfo) {
51  R__LOCKGUARD(gInterpreterMutex);
52  fInfo = gCling->MethodInfo_FactoryCopy(orig.fInfo);
53  fMangledName = orig.fMangledName;
54  } else
55  fInfo = 0;
56  fMethodArgs = 0;
57 }
58 
59 ////////////////////////////////////////////////////////////////////////////////
60 /// Assignment operator.
61 
62 TFunction& TFunction::operator=(const TFunction &rhs)
63 {
64  if (this != &rhs) {
65  R__LOCKGUARD(gInterpreterMutex);
66  gCling->MethodInfo_Delete(fInfo);
67  if (fMethodArgs) fMethodArgs->Delete();
68  delete fMethodArgs;
69  if (rhs.fInfo) {
70  fInfo = gCling->MethodInfo_FactoryCopy(rhs.fInfo);
71  SetName(gCling->MethodInfo_Name(fInfo));
72  SetTitle(gCling->MethodInfo_Title(fInfo));
73  fMangledName = gCling->MethodInfo_GetMangledName(fInfo);
74  } else
75  fInfo = 0;
76  fMethodArgs = 0;
77  }
78  return *this;
79 }
80 
81 ////////////////////////////////////////////////////////////////////////////////
82 /// TFunction dtor deletes adopted CINT MethodInfo.
83 
84 TFunction::~TFunction()
85 {
86  R__LOCKGUARD(gInterpreterMutex);
87  gCling->MethodInfo_Delete(fInfo);
88 
89  if (fMethodArgs) fMethodArgs->Delete();
90  delete fMethodArgs;
91 }
92 
93 ////////////////////////////////////////////////////////////////////////////////
94 /// Clone method.
95 
96 TObject *TFunction::Clone(const char *newname) const
97 {
98  TNamed *newobj = new TFunction(*this);
99  if (newname && strlen(newname)) newobj->SetName(newname);
100  return newobj;
101 }
102 
103 ////////////////////////////////////////////////////////////////////////////////
104 /// Using the CINT method arg information to create a complete signature string.
105 
106 void TFunction::CreateSignature()
107 {
108  R__LOCKGUARD(gInterpreterMutex);
109  gCling->MethodInfo_CreateSignature(fInfo, fSignature);
110 }
111 
112 ////////////////////////////////////////////////////////////////////////////////
113 /// Return signature of function.
114 
115 const char *TFunction::GetSignature()
116 {
117  if (fInfo && fSignature.IsNull())
118  CreateSignature();
119 
120  return fSignature.Data();
121 }
122 
123 ////////////////////////////////////////////////////////////////////////////////
124 /// Return list containing the TMethodArgs of a TFunction.
125 
126 TList *TFunction::GetListOfMethodArgs()
127 {
128  if (!fMethodArgs && fInfo) {
129  if (!gInterpreter)
130  Fatal("GetListOfMethodArgs", "gInterpreter not initialized");
131 
132  gInterpreter->CreateListOfMethodArgs(this);
133  }
134  return fMethodArgs;
135 }
136 
137 ////////////////////////////////////////////////////////////////////////////////
138 /// Get full type description of function return type, e,g.: "class TDirectory*".
139 
140 const char *TFunction::GetReturnTypeName() const
141 {
142  R__LOCKGUARD(gInterpreterMutex);
143  if (fInfo == 0 || gCling->MethodInfo_Type(fInfo) == 0) return "Unknown";
144  return gCling->MethodInfo_TypeName(fInfo);
145 }
146 
147 ////////////////////////////////////////////////////////////////////////////////
148 /// Get the normalized name of the return type. A normalized name is fully
149 /// qualified and has all typedef desugared except for the 'special' typedef
150 /// which include Double32_t, Float16_t, [U]Long64_t and std::string. It
151 /// also has std:: removed [This is subject to change].
152 ///
153 
154 std::string TFunction::GetReturnTypeNormalizedName() const
155 {
156  R__LOCKGUARD(gInterpreterMutex);
157  if (fInfo == 0 || gCling->MethodInfo_Type(fInfo) == 0) return "Unknown";
158  return gCling->MethodInfo_TypeNormalizedName(fInfo);
159 }
160 
161 ////////////////////////////////////////////////////////////////////////////////
162 /// Number of function arguments.
163 
164 Int_t TFunction::GetNargs() const
165 {
166  if (fInfo) return gCling->MethodInfo_NArg(fInfo);
167  else if (fMethodArgs) return fMethodArgs->GetEntries();
168  else return 0;
169 }
170 
171 ////////////////////////////////////////////////////////////////////////////////
172 /// Number of function optional (default) arguments.
173 
174 Int_t TFunction::GetNargsOpt() const
175 {
176  // FIXME: when unload this is an over-estimate.
177  return fInfo ? gCling->MethodInfo_NDefaultArg(fInfo) : GetNargs();
178 }
179 
180 ////////////////////////////////////////////////////////////////////////////////
181 /// Get property description word. For meaning of bits see EProperty.
182 
183 Long_t TFunction::Property() const
184 {
185  return fInfo ? gCling->MethodInfo_Property(fInfo) : 0;
186 }
187 
188 ////////////////////////////////////////////////////////////////////////////////
189 /// Get property description word. For meaning of bits see EProperty.
190 
191 Long_t TFunction::ExtraProperty() const
192 {
193  return fInfo ? gCling->MethodInfo_ExtraProperty(fInfo) : 0;
194 }
195 
196 ////////////////////////////////////////////////////////////////////////////////
197 
198 TDictionary::DeclId_t TFunction::GetDeclId() const
199 {
200  return gInterpreter->GetDeclId(fInfo);
201 }
202 
203 ////////////////////////////////////////////////////////////////////////////////
204 /// Return pointer to the interface method. Using this pointer we
205 /// can find which TFunction belongs to a CINT MethodInfo object.
206 /// Both need to have the same InterfaceMethod pointer.
207 
208 void *TFunction::InterfaceMethod() const
209 {
210  return fInfo ? gCling->MethodInfo_InterfaceMethod(fInfo) : 0;
211 }
212 
213 ////////////////////////////////////////////////////////////////////////////////
214 /// Return true if this function object is pointing to a currently
215 /// loaded function. If a function is unloaded after the TFunction
216 /// is created, the TFunction will be set to be invalid.
217 
218 Bool_t TFunction::IsValid()
219 {
220  // Register the transaction when checking the validity of the object.
221  if (!fInfo && UpdateInterpreterStateMarker()) {
222  // Only for global functions. For data member functions TMethod does it.
223  DeclId_t newId = gInterpreter->GetFunction(0, fName);
224  if (newId) {
225  MethodInfo_t *info = gInterpreter->MethodInfo_Factory(newId);
226  Update(info);
227  }
228  return newId != 0;
229  }
230  return fInfo != 0;
231 }
232 
233 ////////////////////////////////////////////////////////////////////////////////
234 /// Returns the mangled name as defined by CINT, or 0 in case of error.
235 
236 const char *TFunction::GetMangledName() const
237 {
238  return fMangledName;
239 }
240 
241 ////////////////////////////////////////////////////////////////////////////////
242 /// Returns the prototype of a function as defined by CINT, or 0 in
243 /// case of error.
244 
245 const char *TFunction::GetPrototype() const
246 {
247  if (fInfo) {
248  R__LOCKGUARD(gInterpreterMutex);
249  return gCling->MethodInfo_GetPrototype(fInfo);
250  } else
251  return 0;
252 }
253 
254 ////////////////////////////////////////////////////////////////////////////////
255 /// List TFunction name and title.
256 
257 void TFunction::ls(Option_t *options /* ="" */) const
258 {
259  TDictionary::ls(options);
260  TROOT::IndentLevel();
261  std::cout << " " << GetPrototype() << '\n';
262 }
263 
264 ////////////////////////////////////////////////////////////////////////////////
265 /// Print TFunction name and title.
266 
267 void TFunction::Print(Option_t *options /* ="" */) const
268 {
269  TDictionary::Print(options);
270 }
271 
272 ////////////////////////////////////////////////////////////////////////////////
273 /// Update the TFunction to reflect the new info.
274 ///
275 /// This can be used to implement unloading (info == 0) and then reloading
276 /// (info being the 'new' decl address).
277 
278 Bool_t TFunction::Update(MethodInfo_t *info)
279 {
280  if (info == 0) {
281 
282  if (fInfo) {
283  R__LOCKGUARD(gInterpreterMutex);
284  gCling->MethodInfo_Delete(fInfo);
285  }
286  fInfo = 0;
287  if (fMethodArgs) {
288  for (Int_t i = 0; i < fMethodArgs->LastIndex() + 1; i ++) {
289  TMethodArg *arg = (TMethodArg *) fMethodArgs->At( i );
290  arg->Update(0);
291  }
292  }
293  return kTRUE;
294  } else {
295  if (fInfo) {
296  R__LOCKGUARD(gInterpreterMutex);
297  gCling->MethodInfo_Delete(fInfo);
298  }
299  fInfo = info;
300  TString newMangledName = gCling->MethodInfo_GetMangledName(fInfo);
301  if (newMangledName != fMangledName) {
302  Error("Update","TFunction object updated with the 'wrong' MethodInfo (%s vs %s).",
303  fMangledName.Data(),newMangledName.Data());
304  fInfo = 0;
305  return false;
306  }
307  SetTitle(gCling->MethodInfo_Title(fInfo));
308  if (fMethodArgs) {
309  MethodArgInfo_t *arg = gCling->MethodArgInfo_Factory(fInfo);
310  Int_t i = 0;
311  R__LOCKGUARD(gInterpreterMutex);
312  while (gCling->MethodArgInfo_Next(arg)) {
313  if (gCling->MethodArgInfo_IsValid(arg)) {
314  MethodArgInfo_t *new_arg = gCling->MethodArgInfo_FactoryCopy(arg);
315  ((TMethodArg *) fMethodArgs->At( i ))->Update(new_arg);
316  ++i;
317  }
318  }
319  }
320  return kTRUE;
321  }
322 }