1 /************************************************************************
2 ************************************************************************
3 FAUST compiler
4 Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
5 ---------------------------------------------------------------------
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ************************************************************************
20 ************************************************************************/
21
22 #ifndef _CODE_CONTAINER_H
23 #define _CODE_CONTAINER_H
24
25 #include <string>
26
27 #include "Text.hh"
28 #include "code_loop.hh"
29 #include "description.hh"
30 #include "dsp_factory.hh"
31 #include "export.hh"
32 #include "floats.hh"
33 #include "garbageable.hh"
34 #include "instructions.hh"
35 #include "json_instructions.hh"
36 #include "property.hh"
37 #include "sigtype.hh"
38 #include "tlib.hh"
39
40 #ifdef WIN32
41 #pragma warning(disable : 4250)
42 #endif
43
44 // The name of 'count' parameter
45 #define fFullCount string("count")
46
47 #define fTableName string("table")
48
49 class TextInstVisitor;
50
51 class CodeContainer : public virtual Garbageable {
52 protected:
53 list<CodeContainer*> fSubContainers;
54 CodeContainer* fParentContainer; ///< Container in which this Container is embedded, null if toplevel Container
55
56 int fNumInputs;
57 int fNumOutputs;
58
59 int fNumActives; ///< number of active controls in the UI (sliders, buttons, etc.)
60 int fNumPassives; ///< number of passive widgets in the UI (bargraphs, etc.)
61
62 int fSubContainerType;
63 bool fGeneratedSR;
64
65 string fKlassName;
66
67 // Declaration part
68 BlockInst* fExtGlobalDeclarationInstructions;
69 BlockInst* fGlobalDeclarationInstructions;
70 BlockInst* fDeclarationInstructions;
71
72 // Init method
73 BlockInst* fInitInstructions;
74 BlockInst* fResetUserInterfaceInstructions;
75 BlockInst* fClearInstructions;
76 BlockInst* fPostInitInstructions;
77
78 // To be used in allocate method (or constructor)
79 BlockInst* fAllocateInstructions;
80
81 // To be used in delete method
82 BlockInst* fDestroyInstructions;
83
84 // Static init method
85 BlockInst* fStaticInitInstructions;
86 BlockInst* fPostStaticInitInstructions;
87
88 // Static destroy method
89 BlockInst* fStaticDestroyInstructions;
90
91 // Compute method
92 BlockInst* fComputeBlockInstructions; // Before DSP loop
93 BlockInst* fPostComputeBlockInstructions; // After DSP loop
94
95 // Additional functions generated in -fun mode
96 BlockInst* fComputeFunctions;
97
98 // User interface
99 BlockInst* fUserInterfaceInstructions;
100
101 set<string> fIncludeFileSet;
102 set<string> fLibrarySet;
103
104 // DAG of loops
105 CodeLoop* fCurLoop;
106
107 property<CodeLoop*> fLoopProperty; ///< loops used to compute some signals
108
109 list<string> fUICode;
110 list<string> fUIMacro;
111 list<string> fUIMacroActives;
112 list<string> fUIMacroPassives;
113
merge(set<string> & dst,set<string> & src)114 void merge(set<string>& dst, set<string>& src)
115 {
116 for (const auto& i : src) dst.insert(i);
117 }
118
collectIncludeFile(set<string> & S)119 void collectIncludeFile(set<string>& S)
120 {
121 for (const auto& k : fSubContainers) k->collectIncludeFile(S);
122 merge(S, fIncludeFileSet);
123 }
124
collectLibrary(set<string> & S)125 void collectLibrary(set<string>& S)
126 {
127 for (const auto& k : fSubContainers) k->collectLibrary(S);
128 merge(S, fLibrarySet);
129 }
130
131 void generateDAGLoopAux(CodeLoop* loop, BlockInst* loop_code, DeclareVarInst* count, int loop_num,
132 bool omp = false);
133 void generateDAGLoopInternal(CodeLoop* loop, BlockInst* block, DeclareVarInst* count, bool omp);
134
printHeader(ostream & dst)135 void printHeader(ostream& dst)
136 {
137 // defines the metadata we want to print as comments at the begin of in the file
138 set<Tree> selectedKeys;
139 selectedKeys.insert(tree("name"));
140 selectedKeys.insert(tree("author"));
141 selectedKeys.insert(tree("copyright"));
142 selectedKeys.insert(tree("license"));
143 selectedKeys.insert(tree("version"));
144
145 dst << "/* ------------------------------------------------------------" << endl;
146 for (const auto& i : gGlobal->gMetaDataSet) {
147 if (selectedKeys.count(i.first)) {
148 dst << *(i.first);
149 const char* sep = ": ";
150 for (const auto& j : i.second) {
151 dst << sep << *j;
152 sep = ", ";
153 }
154 dst << endl;
155 }
156 }
157
158 dst << "Code generated with Faust " << FAUSTVERSION << " (https://faust.grame.fr)" << endl;
159 dst << "Compilation options: ";
160 stringstream options;
161 gGlobal->printCompilationOptions(options);
162 dst << options.str();
163 dst << "\n------------------------------------------------------------ */" << endl;
164 }
165
generateSR()166 virtual void generateSR()
167 {
168 if (!fGeneratedSR) {
169 pushDeclare(InstBuilder::genDecStructVar("fSampleRate", InstBuilder::genInt32Typed()));
170 }
171 pushPreInitMethod(
172 InstBuilder::genStoreStructVar("fSampleRate", InstBuilder::genLoadFunArgsVar("sample_rate")));
173 }
174
175 BlockInst* inlineSubcontainersFunCalls(BlockInst* block);
176
177 public:
178 CodeContainer();
179 void initialize(int numInputs, int numOutputs);
180 virtual ~CodeContainer();
181
182 void printMacros(ostream& fout, int n);
183
getCurLoop()184 CodeLoop* getCurLoop() { return fCurLoop; }
185
setParentContainers(CodeContainer * parent)186 void setParentContainers(CodeContainer* parent) { fParentContainer = parent; }
getParentContainer()187 CodeContainer* getParentContainer() { return fParentContainer; }
getTopParentContainer()188 CodeContainer* getTopParentContainer()
189 {
190 return (fParentContainer != 0) ? fParentContainer->getTopParentContainer() : this;
191 }
192
193 // Returns the name of the class
getFullClassName()194 string getFullClassName()
195 {
196 return (fParentContainer != 0) ? (fParentContainer->getFullClassName() + "::" + getClassName())
197 : getClassName();
198 }
199
setGeneratedSR()200 void setGeneratedSR() { fGeneratedSR = true; }
201
202 void openLoop(const string& index_name, int size = 0);
203 void openLoop(Tree recsymbol, const string& index_name, int size = 0);
204 void closeLoop(Tree sig);
205
inputs()206 int inputs() { return fNumInputs; }
outputs()207 int outputs() { return fNumOutputs; }
208
setInputs(int inputs)209 void setInputs(int inputs) { fNumInputs = inputs; }
setOutputs(int outputs)210 void setOutputs(int outputs) { fNumOutputs = outputs; }
211
addSubContainer(CodeContainer * container)212 void addSubContainer(CodeContainer* container) { fSubContainers.push_back(container); }
213
addIncludeFile(const string & str)214 void addIncludeFile(const string& str) { fIncludeFileSet.insert(str); }
addLibrary(const string & str)215 void addLibrary(const string& str) { fLibrarySet.insert(str); }
216
217 void printLibrary(ostream& fout);
218 void printIncludeFile(ostream& fout);
219
220 void setLoopProperty(Tree sig, CodeLoop* l); ///< Store the loop used to compute a signal
221 bool getLoopProperty(Tree sig, CodeLoop*& l); ///< Returns the loop used to compute a signal
222 void listAllLoopProperties(Tree sig, set<CodeLoop*>&, set<Tree>& visited); ///< Returns all the loop used to compute a signal
223
224 void printGraphDotFormat(ostream& fout);
225
226 void transformDAG(DispatchVisitor* visitor);
227 void computeForwardDAG(lclgraph dag, int& loop_count, vector<int>& ready_loop);
228 void sortDeepFirstDAG(CodeLoop* l, set<CodeLoop*>& visited, list<CodeLoop*>& result);
229
230 // Should be implemented in subclasses
generateLocalInputs(BlockInst * loop_code,const string & index)231 virtual void generateLocalInputs(BlockInst* loop_code, const string& index) { faustassert(false); }
generateLocalOutputs(BlockInst * loop_code,const string & index)232 virtual void generateLocalOutputs(BlockInst* loop_code, const string& index) { faustassert(false); }
233
234 virtual DeclareFunInst* generateAllocate(const string& name, const string& obj, bool ismethod, bool isvirtual);
235 virtual DeclareFunInst* generateDestroy(const string& name, const string& obj, bool ismethod, bool isvirtual);
236
237 DeclareFunInst* generateGetIO(const string& name, const string& obj, int io, bool ismethod, bool isvirtual);
238 DeclareFunInst* generateGetInputs(const string& name, const string& obj, bool ismethod, bool isvirtual);
239 DeclareFunInst* generateGetOutputs(const string& name, const string& obj, bool ismethod, bool isvirtual);
240
241 DeclareFunInst* generateGetIORate(const string& name, const string& obj, vector<int>& io, bool ismethod,
242 bool isvirtual);
243
generateClassInit(const string & name)244 virtual DeclareFunInst* generateClassInit(const string& name)
245 {
246 faustassert(false);
247 return nullptr;
248 }
249 virtual DeclareFunInst* generateInstanceClear(const string& name, const string& obj, bool ismethod, bool isvirtual);
250
251 virtual DeclareFunInst* generateInstanceConstants(const string& name, const string& obj, bool ismethod,
252 bool isvirtual);
253
generateInstanceResetUserInterface(const string & name,const string & obj,bool ismethod,bool isvirtual)254 virtual DeclareFunInst* generateInstanceResetUserInterface(const string& name, const string& obj, bool ismethod,
255 bool isvirtual)
256 {
257 faustassert(false);
258 return nullptr;
259 }
260
261 virtual DeclareFunInst* generateComputeFun(const string& name, const string& obj, bool ismethod, bool isvirtual);
262
generateComputeAux()263 virtual BlockInst* generateComputeAux()
264 {
265 faustassert(false);
266 return nullptr;
267 }
268
269 virtual DeclareFunInst* generateStaticInitFun(const string& name, bool isstatic);
270 virtual DeclareFunInst* generateInstanceInitFun(const string& name, const string& obj, bool ismethod,
271 bool isvirtual);
272 virtual DeclareFunInst* generateFillFun(const string& name, const string& obj, bool ismethod, bool isvirtual);
273
274 DeclareFunInst* generateInit(const string& name, const string& obj, bool ismethod, bool isvirtual);
275 DeclareFunInst* generateInstanceInit(const string& name, const string& obj, bool ismethod, bool isvirtual);
276 DeclareFunInst* generateGetSampleRate(const string& name, const string& obj, bool ismethod, bool isvirtual);
277
278 DeclareFunInst* generateCalloc();
279 DeclareFunInst* generateFree();
280
281 DeclareFunInst* generateNewDsp(const string& name, int size);
282 DeclareFunInst* generateDeleteDsp(const string& name, const string& obj);
283
284 void produceInfoFunctions(int tabs, const string& classname, const string& obj, bool ismethod, bool isvirtual,
285 TextInstVisitor* producer);
286
287 void generateDAGLoop(BlockInst* loop_code, DeclareVarInst* count);
288
289 template <typename REAL>
generateMetaData(JSONUIReal<REAL> * json)290 void generateMetaData(JSONUIReal<REAL>* json)
291 {
292 // Add global metadata
293 for (const auto& i : gGlobal->gMetaDataSet) {
294 if (i.first != tree("author")) {
295 stringstream str1, str2;
296 str1 << *(i.first);
297 str2 << **(i.second.begin());
298 string res1 = str1.str();
299 string res2 = unquote(str2.str());
300 json->declare(res1.c_str(), res2.c_str());
301 } else {
302 for (set<Tree>::iterator j = i.second.begin(); j != i.second.end(); j++) {
303 if (j == i.second.begin()) {
304 stringstream str1, str2;
305 str1 << *(i.first);
306 str2 << **j;
307 string res1 = str1.str();
308 string res2 = unquote(str2.str());
309 json->declare(res1.c_str(), res2.c_str());
310 } else {
311 stringstream str2;
312 str2 << **j;
313 string res2 = unquote(str2.str());
314 json->declare("contributor", res2.c_str());
315 }
316 }
317 }
318 }
319 }
320
321 template <typename REAL>
generateJSONFile()322 void generateJSONFile()
323 {
324 JSONInstVisitor<REAL> json_visitor;
325 generateJSON(&json_visitor);
326 ofstream xout(subst("$0.json", gGlobal->makeDrawPath()).c_str());
327 xout << json_visitor.JSON();
328 }
329
330 template <typename REAL>
generateJSON(JSONInstVisitor<REAL> * visitor)331 void generateJSON(JSONInstVisitor<REAL>* visitor)
332 {
333 // Prepare compilation options
334 stringstream compile_options;
335 gGlobal->printCompilationOptions(compile_options);
336
337 // "name", "filename" found in medata
338 visitor->init("", "", fNumInputs, fNumOutputs, -1, "", "", FAUSTVERSION, compile_options.str(),
339 gGlobal->gReader.listLibraryFiles(), gGlobal->gImportDirList, -1, std::map<std::string, int>());
340
341 generateUserInterface(visitor);
342 generateMetaData(visitor);
343 }
344
345 template <typename REAL>
generateJSON()346 string generateJSON()
347 {
348 JSONInstVisitor<REAL> visitor;
349 generateJSON(&visitor);
350 return visitor.JSON(true);
351 }
352
353 /* Can be overridden by subclasses to transform the FIR before the actual code generation */
354 virtual void processFIR(void);
355
356 virtual BlockInst* flattenFIR(void);
357
358 // Fill code for each method
pushDeclare(StatementInst * inst)359 StatementInst* pushDeclare(StatementInst* inst)
360 {
361 fDeclarationInstructions->pushBackInst(inst);
362 // TODO : add inter-loop vectors in current loop
363 return inst;
364 }
365
pushGlobalDeclare(StatementInst * inst)366 StatementInst* pushGlobalDeclare(StatementInst* inst)
367 {
368 fGlobalDeclarationInstructions->pushBackInst(inst);
369 return inst;
370 }
371
pushExtGlobalDeclare(StatementInst * inst)372 StatementInst* pushExtGlobalDeclare(StatementInst* inst)
373 {
374 fExtGlobalDeclarationInstructions->pushBackInst(inst);
375 return inst;
376 }
377
378 ValueInst* pushFunction(const string& name, Typed::VarType result, vector<Typed::VarType>& types,
379 const list<ValueInst*>& args);
380
generateExtGlobalDeclarations(InstVisitor * visitor)381 void generateExtGlobalDeclarations(InstVisitor* visitor)
382 {
383 if (fExtGlobalDeclarationInstructions->fCode.size() > 0) {
384 fExtGlobalDeclarationInstructions->accept(visitor);
385 }
386 }
387
generateGlobalDeclarations(InstVisitor * visitor)388 void generateGlobalDeclarations(InstVisitor* visitor)
389 {
390 if (fGlobalDeclarationInstructions->fCode.size() > 0) {
391 fGlobalDeclarationInstructions->accept(visitor);
392 }
393 }
394
generateDeclarations(InstVisitor * visitor)395 void generateDeclarations(InstVisitor* visitor)
396 {
397 if (fDeclarationInstructions->fCode.size() > 0) {
398 fDeclarationInstructions->accept(visitor);
399 }
400 }
401
generateInit(InstVisitor * visitor)402 void generateInit(InstVisitor* visitor)
403 {
404 if (fInitInstructions->fCode.size() > 0) {
405 fInitInstructions->accept(visitor);
406 }
407
408 if (fPostInitInstructions->fCode.size() > 0) {
409 fPostInitInstructions->accept(visitor);
410 }
411 }
412
generateResetUserInterface(InstVisitor * visitor)413 void generateResetUserInterface(InstVisitor* visitor)
414 {
415 if (fResetUserInterfaceInstructions->fCode.size() > 0) {
416 fResetUserInterfaceInstructions->accept(visitor);
417 }
418 }
419
generateClear(InstVisitor * visitor)420 void generateClear(InstVisitor* visitor)
421 {
422 if (fClearInstructions->fCode.size() > 0) {
423 fClearInstructions->accept(visitor);
424 }
425 }
426
generateStaticInit(InstVisitor * visitor)427 void generateStaticInit(InstVisitor* visitor)
428 {
429 if (fStaticInitInstructions->fCode.size() > 0) {
430 fStaticInitInstructions->accept(visitor);
431 }
432
433 if (fPostStaticInitInstructions->fCode.size() > 0) {
434 fPostStaticInitInstructions->accept(visitor);
435 }
436 }
437
generateStaticDestroy(InstVisitor * visitor)438 void generateStaticDestroy(InstVisitor* visitor)
439 {
440 if (fStaticDestroyInstructions->fCode.size() > 0) {
441 fStaticDestroyInstructions->accept(visitor);
442 }
443 }
444
generateUserInterface(InstVisitor * visitor)445 void generateUserInterface(InstVisitor* visitor)
446 {
447 if (fUserInterfaceInstructions->fCode.size() > 0) {
448 fUserInterfaceInstructions->accept(visitor);
449 }
450 }
451
generateComputeFunctions(InstVisitor * visitor)452 void generateComputeFunctions(InstVisitor* visitor)
453 {
454 if (fComputeFunctions->fCode.size() > 0) {
455 fComputeFunctions->accept(visitor);
456 }
457 }
458
generateComputeBlock(InstVisitor * visitor)459 void generateComputeBlock(InstVisitor* visitor)
460 {
461 if (fComputeBlockInstructions->fCode.size() > 0) {
462 fComputeBlockInstructions->accept(visitor);
463 }
464 }
465
generatePostComputeBlock(InstVisitor * visitor)466 void generatePostComputeBlock(InstVisitor* visitor)
467 {
468 if (fPostComputeBlockInstructions->fCode.size() > 0) {
469 fPostComputeBlockInstructions->accept(visitor);
470 }
471 }
472
generateAllocate(InstVisitor * visitor)473 void generateAllocate(InstVisitor* visitor)
474 {
475 if (fAllocateInstructions->fCode.size() > 0) {
476 fAllocateInstructions->accept(visitor);
477 }
478 }
479
generateDestroy(InstVisitor * visitor)480 void generateDestroy(InstVisitor* visitor)
481 {
482 if (fDestroyInstructions->fCode.size() > 0) {
483 fDestroyInstructions->accept(visitor);
484 }
485 }
486
pushInitMethod(StatementInst * inst)487 StatementInst* pushInitMethod(StatementInst* inst)
488 {
489 fInitInstructions->pushBackInst(inst);
490 return inst;
491 }
pushClearMethod(StatementInst * inst)492 StatementInst* pushClearMethod(StatementInst* inst)
493 {
494 fClearInstructions->pushBackInst(inst);
495 return inst;
496 }
pushResetUIInstructions(StatementInst * inst)497 StatementInst* pushResetUIInstructions(StatementInst* inst)
498 {
499 fResetUserInterfaceInstructions->pushBackInst(inst);
500 return inst;
501 }
pushPostInitMethod(StatementInst * inst)502 StatementInst* pushPostInitMethod(StatementInst* inst)
503 {
504 fPostInitInstructions->pushBackInst(inst);
505 return inst;
506 }
pushPreInitMethod(StatementInst * inst)507 StatementInst* pushPreInitMethod(StatementInst* inst)
508 {
509 fInitInstructions->pushFrontInst(inst);
510 return inst;
511 }
512
pushUserInterfaceMethod(StatementInst * inst)513 StatementInst* pushUserInterfaceMethod(StatementInst* inst)
514 {
515 fUserInterfaceInstructions->pushBackInst(inst);
516 return inst;
517 }
518
pushAllocateMethod(StatementInst * inst)519 StatementInst* pushAllocateMethod(StatementInst* inst)
520 {
521 fAllocateInstructions->pushBackInst(inst);
522 return inst;
523 }
pushDestroyMethod(StatementInst * inst)524 StatementInst* pushDestroyMethod(StatementInst* inst)
525 {
526 fDestroyInstructions->pushBackInst(inst);
527 return inst;
528 }
529
pushStaticInitMethod(StatementInst * inst)530 StatementInst* pushStaticInitMethod(StatementInst* inst)
531 {
532 fStaticInitInstructions->pushBackInst(inst);
533 return inst;
534 }
pushStaticDestroyMethod(StatementInst * inst)535 StatementInst* pushStaticDestroyMethod(StatementInst* inst)
536 {
537 fStaticDestroyInstructions->pushBackInst(inst);
538 return inst;
539 }
pushPostStaticInitMethod(StatementInst * inst)540 StatementInst* pushPostStaticInitMethod(StatementInst* inst)
541 {
542 fPostStaticInitInstructions->pushBackInst(inst);
543 return inst;
544 }
545
pushComputeBlockMethod(StatementInst * inst)546 StatementInst* pushComputeBlockMethod(StatementInst* inst)
547 {
548 fComputeBlockInstructions->pushBackInst(inst);
549 return inst;
550 }
pushPostComputeBlockMethod(StatementInst * inst)551 StatementInst* pushPostComputeBlockMethod(StatementInst* inst)
552 {
553 fPostComputeBlockInstructions->pushBackInst(inst);
554 return inst;
555 }
556
pushOtherComputeMethod(StatementInst * inst)557 StatementInst* pushOtherComputeMethod(StatementInst* inst)
558 {
559 fComputeFunctions->pushBackInst(inst);
560 return inst;
561 }
562
pushPreComputeDSPMethod(StatementInst * inst)563 StatementInst* pushPreComputeDSPMethod(StatementInst* inst) { return fCurLoop->pushPreComputeDSPMethod(inst); }
pushComputeDSPMethod(StatementInst * inst)564 StatementInst* pushComputeDSPMethod(StatementInst* inst) { return fCurLoop->pushComputeDSPMethod(inst); }
pushPostComputeDSPMethod(StatementInst * inst)565 StatementInst* pushPostComputeDSPMethod(StatementInst* inst) { return fCurLoop->pushPostComputeDSPMethod(inst); }
566
generateSubContainers()567 void generateSubContainers()
568 {
569 for (const auto& it : fSubContainers) {
570 it->produceInternal();
571 }
572 }
573
574 // merge declaration part
mergeSubContainers()575 void mergeSubContainers()
576 {
577 for (const auto& it : fSubContainers) {
578 // Merge the subcontainer in the main one
579 fExtGlobalDeclarationInstructions->merge(it->fExtGlobalDeclarationInstructions);
580 fGlobalDeclarationInstructions->merge(it->fGlobalDeclarationInstructions);
581 fDeclarationInstructions->merge(it->fDeclarationInstructions);
582 // Then clear it
583 it->fGlobalDeclarationInstructions->fCode.clear();
584 it->fExtGlobalDeclarationInstructions->fCode.clear();
585 it->fDeclarationInstructions->fCode.clear();
586 }
587 }
588
getSubContainers()589 size_t getSubContainers() { return fSubContainers.size(); }
590
getTableName()591 const string getTableName() { return fTableName; }
getClassName()592 const string getClassName() { return fKlassName; }
getFaustPowerName()593 const string getFaustPowerName() { return fKlassName + "_faustpower"; }
594
595 // UI construction
addUIMacro(const string & str)596 void addUIMacro(const string& str) { fUIMacro.push_back(str); }
addUIMacroActives(const string & str)597 void addUIMacroActives(const string& str) { fUIMacroActives.push_back(str); }
addUIMacroPassives(const string & str)598 void addUIMacroPassives(const string& str) { fUIMacroPassives.push_back(str); }
addUICode(const string & str)599 void addUICode(const string& str) { fUICode.push_back(str); }
600
601 virtual CodeContainer* createScalarContainer(const string& name, int sub_container_type) = 0;
602
603 virtual void produceInternal() = 0;
604
printHeader()605 virtual void printHeader() {}
printFloatDef()606 virtual void printFloatDef() {}
printFooter()607 virtual void printFooter() {}
produceClass()608 virtual void produceClass() {}
609
dump(ostream * dst)610 virtual void dump(ostream* dst) {}
611
incUIActiveCount()612 void incUIActiveCount() { fNumActives++; }
incUIPassiveCount()613 void incUIPassiveCount() { fNumPassives++; }
614
produceFactory()615 virtual dsp_factory_base* produceFactory()
616 {
617 faustassert(false);
618 return nullptr;
619 }
620
621 int fInt32ControlNum; // number of 'int32' intermediate control values
622 int fRealControlNum; // number of 'real' intermediate control values
623 };
624
isElement(const set<CodeLoop * > & S,CodeLoop * l)625 inline bool isElement(const set<CodeLoop*>& S, CodeLoop* l)
626 {
627 return S.find(l) != S.end();
628 }
629
630 #endif
631