Logo ROOT  
Reference Guide
TModuleGenerator.cxx
Go to the documentation of this file.
1// @(#)root/utils:$Id$
2// Author: Axel Naumann, 2-13-07-02
3// Author: Danilo Piparo, 2013, 2014
4
5/*************************************************************************
6 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12
13////////////////////////////////////////////////////////////////////////////////
14//
15// PCM writer.
16//
17////////////////////////////////////////////////////////////////////////////////
18
19#include "TModuleGenerator.h"
20
21#include "TClingUtils.h"
22#include "RConfigure.h"
23#include <ROOT/RConfig.hxx>
24
25#include "cling/Interpreter/CIFactory.h"
26#include "clang/Basic/SourceManager.h"
27#include "clang/Frontend/CompilerInstance.h"
28#include "clang/Lex/HeaderSearch.h"
29#include "clang/Lex/Preprocessor.h"
30#include "llvm/Support/Path.h"
31
32#include <map>
33
34#ifndef R__WIN32
35#include <unistd.h>
36#endif
37
38#include <iostream>
39
40using namespace ROOT;
41using namespace clang;
42
43////////////////////////////////////////////////////////////////////////////////
44
45TModuleGenerator::TModuleGenerator(CompilerInstance *CI,
46 bool inlineInputHeaders,
47 const std::string &shLibFileName,
48 bool writeEmptyRootPCM):
49 fCI(CI),
50 fIsPCH(shLibFileName == "allDict.cxx"),
51 fIsInPCH(writeEmptyRootPCM),
52 fInlineInputHeaders(inlineInputHeaders),
53 fDictionaryName(llvm::sys::path::stem(shLibFileName)),
54 fDemangledDictionaryName(llvm::sys::path::stem(shLibFileName)),
55 fModuleDirName(llvm::sys::path::parent_path(shLibFileName)),
56 fErrorCount(0)
57{
58 // Need to resolve _where_ to create the pcm
59 // We default in the lib subdirectory
60 // otherwise we put it in the same directory as the dictionary file (for ACLiC)
61 if (fModuleDirName.empty()) {
62 fModuleDirName = "./";
63 } else {
64 fModuleDirName += "/";
65 }
66
69
70 // Clean the dictionary name from characters which are not accepted in C++
71 std::string tmpName = fDictionaryName;
72 fDictionaryName.clear();
74
75 // .pcm -> .pch
76 if (IsPCH()) fModuleFileName[fModuleFileName.length() - 1] = 'h';
77
78 // Add a random string to the filename to avoid races.
79 auto makeTempFile = [&](const char *suffix) {
80 llvm::SmallString<64> resultPath;
81 std::string pattern = fModuleDirName + fDictionaryName + "%%%%%%%%%%" + suffix;
82 llvm::sys::fs::createUniqueFile(pattern, resultPath); // NOTE: this creates the (empty) file
83 // Return the full buffer, so caller can use `.c_str()` on the temporary.
84 return resultPath;
85 };
86
87 fUmbrellaName = makeTempFile("_dictUmbrella.h").c_str();
88 fContentName = makeTempFile("_dictContent.h").c_str();
89}
90
92{
93 unlink(fUmbrellaName.c_str());
94 unlink(fContentName.c_str());
95}
96
97////////////////////////////////////////////////////////////////////////////////
98/// Check whether the file's extension is compatible with C or C++.
99/// Return whether source, header, Linkdef or nothing.
100
102TModuleGenerator::GetSourceFileKind(const char *filename) const
103{
104 if (filename[0] == '-') return kSFKNotC;
105
106 if (ROOT::TMetaUtils::IsLinkdefFile(filename)) {
107 return kSFKLinkdef;
108 }
109
110 const size_t len = strlen(filename);
111 const char *ext = filename + len - 1;
112 while (ext >= filename && *ext != '.') --ext;
113 if (ext < filename || *ext != '.') {
114 // This might still be a system header, let's double check
115 // via the FileManager.
116 clang::Preprocessor &PP = fCI->getPreprocessor();
117 clang::HeaderSearch &HdrSearch = PP.getHeaderSearchInfo();
118 const clang::DirectoryLookup *CurDir = nullptr;
119 const clang::FileEntry *hdrFileEntry
120 = HdrSearch.LookupFile(filename, clang::SourceLocation(),
121 true /*isAngled*/, nullptr /*FromDir*/, CurDir,
122 clang::ArrayRef<std::pair<const clang::FileEntry*,
123 const clang::DirectoryEntry*>>(),
124 nullptr /*SearchPath*/,/*RelativePath*/ nullptr,
125 nullptr /*RequestingModule*/, nullptr /*SuggestedModule*/,
126 nullptr /*IsMapped*/, nullptr /*IsFrameworkFound*/);
127 if (hdrFileEntry) {
128 return kSFKHeader;
129 }
130 return kSFKNotC;
131 }
132 ++ext;
133 const size_t lenExt = filename + len - ext;
134
136 switch (lenExt) {
137 case 1: {
138 const char last = toupper(filename[len - 1]);
139 if (last == 'H') ret = kSFKHeader;
140 else if (last == 'C') ret = kSFKSource;
141 break;
142 }
143 case 2: {
144 if (filename[len - 2] == 'h' && filename[len - 1] == 'h')
145 ret = kSFKHeader;
146 else if (filename[len - 2] == 'c' && filename[len - 1] == 'c')
147 ret = kSFKSource;
148 break;
149 }
150 case 3: {
151 const char last = filename[len - 1];
152 if ((last == 'x' || last == 'p')
153 && filename[len - 2] == last) {
154 if (filename[len - 3] == 'h') ret = kSFKHeader;
155 else if (filename[len - 3] == 'c') ret = kSFKSource;
156 }
157 }
158 } // switch extension length
159
160 return ret;
161}
162
163
164static
165std::pair<std::string, std::string> SplitPPDefine(const std::string &in)
166{
167 std::string::size_type posEq = in.find('=');
168 // No equal found: define to 1
169 if (posEq == std::string::npos)
170 return std::make_pair(in, "1");
171
172 // Equal found
173 return std::pair<std::string, std::string>
174 (in.substr(0, posEq), in.substr(posEq + 1, std::string::npos));
175}
176
177////////////////////////////////////////////////////////////////////////////////
178/// Parse -I -D -U headers.h SomethingLinkdef.h.
179
180void TModuleGenerator::ParseArgs(const std::vector<std::string> &args)
181{
182 for (size_t iPcmArg = 1 /*skip argv0*/, nPcmArg = args.size();
183 iPcmArg < nPcmArg; ++iPcmArg) {
184 ESourceFileKind sfk = GetSourceFileKind(args[iPcmArg].c_str());
185 if (sfk == kSFKHeader || sfk == kSFKSource) {
186 fHeaders.push_back(args[iPcmArg]);
187 } else if (sfk == kSFKLinkdef) {
188 fLinkDefFile = args[iPcmArg];
189 } else if (sfk == kSFKNotC && args[iPcmArg][0] == '-') {
190 switch (args[iPcmArg][1]) {
191 case 'I':
192 if (args[iPcmArg] != "-I." && args[iPcmArg] != "-Iinclude") {
193 fCompI.push_back(args[iPcmArg].c_str() + 2);
194 }
195 break;
196 case 'D':
197 if (args[iPcmArg] != "-DTRUE=1" && args[iPcmArg] != "-DFALSE=0"
198 && args[iPcmArg] != "-DG__NOCINTDLL") {
199 fCompD.push_back(SplitPPDefine(args[iPcmArg].c_str() + 2));
200 }
201 break;
202 case 'U':
203 fCompU.push_back(args[iPcmArg].c_str() + 2);
204 break;
205 }
206 }
207 }
208}
209
210////////////////////////////////////////////////////////////////////////////////
211/// Write
212/// #ifndef FOO
213/// # define FOO=bar
214/// #endif
215
216std::ostream &TModuleGenerator::WritePPDefines(std::ostream &out) const
217{
218 for (auto const & strPair : fCompD) {
219 std::string cppname(strPair.first);
220 size_t pos = cppname.find('(');
221 if (pos != std::string::npos) cppname.erase(pos);
222 out << "#ifndef " << cppname << "\n"
223 " #define " << strPair.first;
224 out << " " << strPair.second;
225 out << "\n"
226 "#endif\n";
227 }
228 out << std::endl;
229 return out;
230}
231
232////////////////////////////////////////////////////////////////////////////////
233/// Write
234/// #ifdef FOO
235/// # undef FOO
236/// #endif
237
238std::ostream &TModuleGenerator::WritePPUndefines(std::ostream &out) const
239{
240 for (auto const & undef : fCompU) {
241 out << "#ifdef " << undef << "\n"
242 " #undef " << undef << "\n"
243 "#endif\n";
244 }
245 out << std::endl;
246 return out;
247}
248
249////////////////////////////////////////////////////////////////////////////////
250/// To be replaced with proper pragma handlers.
251
252int WarnIfPragmaOnceDetected(const std::string& fullHeaderPath,
253 const std::string& headerFileContent)
254{
255 std::istringstream headerFile(headerFileContent);
256 std::string line;
257 while(std::getline(headerFile,line)){
258 llvm::StringRef lineRef (line);
259 auto trimmedLineRef = lineRef.trim();
260 if (trimmedLineRef.startswith("#pragma") &&
261 (trimmedLineRef.endswith(" once") || trimmedLineRef.endswith("\tonce"))) {
262 std::cerr << "Error: #pragma once directive detected in header file "
263 << fullHeaderPath
264 << " which was requested to be inlined.\n";
265 return 1;
266 }
267 }
268 return 0;
269}
270
271////////////////////////////////////////////////////////////////////////////////
272
273int ExtractBufferContent(const std::string& fullHeaderPath, std::string& bufferContent)
274{
275 std::ifstream buffer(fullHeaderPath);
276 bufferContent = std::string((std::istreambuf_iterator<char>(buffer)),
277 std::istreambuf_iterator<char>());
278
279 return WarnIfPragmaOnceDetected(fullHeaderPath,bufferContent);
280}
281
282////////////////////////////////////////////////////////////////////////////////
283/// Write
284/// #include "header1.h"
285/// #include "header2.h"
286/// or, if inlining of headers is requested, dump the content of the files.
287
288std::ostream &TModuleGenerator::WritePPIncludes(std::ostream &out) const
289{
290 std::string fullHeaderPath;
291 for (auto const & incl : fHeaders) {
293 bool headerFound = FindHeader(incl,fullHeaderPath);
294 if (!headerFound){
295 ROOT::TMetaUtils::Error(nullptr, "Cannot find header %s: cannot inline it.\n", fullHeaderPath.c_str());
296 continue;
297 }
298
299 std::string bufferContent;
300 fErrorCount += ExtractBufferContent(fullHeaderPath, bufferContent);
301
302 out << bufferContent << std::endl;
303 } else {
304 out << "#include \"" << incl << "\"\n";
305 }
306 }
307 out << std::endl;
308 return out;
309}
310
311////////////////////////////////////////////////////////////////////////////////
312
313std::ostream &TModuleGenerator::WriteStringVec(const std::vector<std::string> &vec,
314 std::ostream &out) const
315{
316 for (auto const & theStr : vec) {
317 out << "\"" << theStr << "\",\n";
318 }
319 out << "nullptr" << std::endl;
320 return out;
321}
322
323////////////////////////////////////////////////////////////////////////////////
324
326 std::ostream &out) const
327{
328 for (auto const & strPair : vec) {
329 out << "\"" << strPair.first;
330 if (!strPair.second.empty()) {
331 out << "=";
332 // Need to escape the embedded quotes.
333 for (const char *c = strPair.second.c_str(); *c != '\0'; ++c) {
334 if (*c == '"') {
335 out << "\\\"";
336 } else {
337 out << *c;
338 }
339 }
340 }
341 out << "\",\n";
342 }
343 out << "nullptr" << std::endl;
344 return out;
345}
346
347
349 const std::string &dictName,
350 const std::string &demangledDictName,
351 const std::vector<std::string> &headerArray,
352 const std::vector<std::string> &includePathArray,
353 const std::string &fwdDeclStringRAW,
354 const std::string &fwdDeclnArgsToKeepString,
355 const std::string &payloadCodeWrapped,
356 const std::string &headersClassesMapString,
357 const std::string &extraIncludes,
358 bool hasCxxModule) const
359{
360 // Dictionary initialization code for loading the module
361 out << "namespace {\n"
362 " void TriggerDictionaryInitialization_" << dictName << "_Impl() {\n"
363 " static const char* headers[] = {\n";
364 WriteStringVec(headerArray, out) << " };\n";
365 out << " static const char* includePaths[] = {\n";
366 WriteStringVec(includePathArray, out)
367 << " };\n";
368
369 out << " static const char* fwdDeclCode = " << fwdDeclStringRAW << ";\n"
370 << " static const char* payloadCode = " << payloadCodeWrapped << ";\n";
371 // classesHeaders may depen on payloadCode
372 out << " static const char* classesHeaders[] = {\n"
373 << headersClassesMapString
374 << "\n};\n";
375 out << " static bool isInitialized = false;\n"
376 " if (!isInitialized) {\n"
377 " TROOT::RegisterModule(\"" << demangledDictName << "\",\n"
378 " headers, includePaths, payloadCode, fwdDeclCode,\n"
379 " TriggerDictionaryInitialization_" << dictName << "_Impl, "
380 << fwdDeclnArgsToKeepString << ", classesHeaders, "
381 << (hasCxxModule ? "/*hasCxxModule*/true" : "/*hasCxxModule*/false")
382 << ");\n"
383 " isInitialized = true;\n"
384 " }\n"
385 " }\n"
386 " static struct DictInit {\n"
387 " DictInit() {\n"
388 " TriggerDictionaryInitialization_" << dictName << "_Impl();\n"
389 " }\n"
390 " } __TheDictionaryInitializer;\n"
391 "}\n"
392 "void TriggerDictionaryInitialization_" << dictName << "() {\n"
393 " TriggerDictionaryInitialization_" << dictName << "_Impl();\n"
394 "}\n";
395}
396
397////////////////////////////////////////////////////////////////////////////////
398
399void TModuleGenerator::WriteRegistrationSource(std::ostream &out, const std::string &fwdDeclnArgsToKeepString,
400 const std::string &headersClassesMapString,
401 const std::string &fwdDeclString, const std::string &extraIncludes, bool hasCxxModule) const
402{
403 if (hasCxxModule) {
404 std::string emptyStr = "\"\"";
406 fwdDeclString, "{}",
407 emptyStr, headersClassesMapString, "0",
408 /*HasCxxModule*/ true);
409 return;
410 }
411
412 std::string fwdDeclStringSanitized = fwdDeclString;
413#ifdef R__WIN32
414 // Visual sudio has a limitation of 2048 characters max in raw strings, so split
415 // the potentially huge DICTFWDDCLS raw string into multiple smaller ones
416 constexpr char from[] = "\n";
417 constexpr char to[] = "\n)DICTFWDDCLS\"\nR\"DICTFWDDCLS(";
418 size_t start_pos = 0;
419 while ((start_pos = fwdDeclStringSanitized.find(from, start_pos)) != std::string::npos) {
420 if (fwdDeclStringSanitized.find(from, start_pos + 1) == std::string::npos) // skip the last
421 break;
422 if ((fwdDeclStringSanitized.at(start_pos + 1) == '}') || (fwdDeclStringSanitized.at(start_pos + 1) == '\n'))
423 start_pos += 2;
424 else {
425 fwdDeclStringSanitized.replace(start_pos, strlen(from), to);
426 start_pos += strlen(to); // In case 'to' contains 'from', like replacing 'x' with 'yx'
427 }
428 }
429#endif
430 std::string fwdDeclStringRAW;
431 if ("nullptr" == fwdDeclStringSanitized || "\"\"" == fwdDeclStringSanitized) {
432 fwdDeclStringRAW = fwdDeclStringSanitized;
433 } else {
434 fwdDeclStringRAW = "R\"DICTFWDDCLS(\n";
435 fwdDeclStringRAW += "#line 1 \"";
436 fwdDeclStringRAW += fDictionaryName +" dictionary forward declarations' payload\"\n";
437 fwdDeclStringRAW += fwdDeclStringSanitized;
438 fwdDeclStringRAW += ")DICTFWDDCLS\"";
439 }
440
441 if (fIsInPCH)
442 fwdDeclStringRAW = "nullptr";
443
444 std::string payloadCode;
445
446 // Increase the value of the diagnostics pointing out from which
447 // dictionary this payload comes from in case of errors
448 payloadCode += "#line 1 \"";
449 payloadCode += fDictionaryName +" dictionary payload\"\n";
450
451 // Add defines and undefines to the payloadCode
452 std::ostringstream definesAndUndefines;
453 // Anticipate the undefines.
454 // Suppose to have a namespace called "declarations" used in R5 for template
455 // instantiations in the header given to genreflex.
456 // Now, in this namespace, objects with some names, typically dummy, will be
457 // present.
458 // If you give such headers to cling to parse, problems will occour, as the
459 // names appear multiple times. One possible solution is to get out of this
460 // with preprocessor defines given to genreflex, redefining "declarations"
461 // to a hash or <project>_<package> via the build system.
462 WritePPUndefines(definesAndUndefines);
463 WritePPDefines(definesAndUndefines);
464 payloadCode += definesAndUndefines.str();
465
466 // If necessary, inline the headers
467 std::string hdrFullPath;
468 std::string inlinedHeaders;
469
470 auto findAndAddToInlineHeaders = [&](const std::string& hdrName) {
471 bool headerFound = FindHeader(hdrName,hdrFullPath);
472 if (!headerFound) {
473 ROOT::TMetaUtils::Error(nullptr, "Cannot find header %s: cannot inline it.\n", hdrName.c_str());
474 } else {
475 std::ifstream headerFile(hdrFullPath.c_str());
476 const std::string headerFileAsStr((std::istreambuf_iterator<char>(headerFile)),
477 std::istreambuf_iterator<char>());
478 inlinedHeaders += headerFileAsStr;
479 }
480 };
481
483 for (auto const & hdrName : fHeaders) {
484 findAndAddToInlineHeaders(hdrName);
485 }
486
487 } else {
488 // Now, if not, just #include them in the payload except for the linkdef
489 // file, if any.
490 for (auto & hdrName : fHeaders) {
491 inlinedHeaders += "#include \"" + hdrName + "\"\n";
492 }
493 }
494
495 if (0 != fLinkDefFile.size() && !fIsPCH) {
496 findAndAddToInlineHeaders(fLinkDefFile);
497 }
498
499 // Recover old genreflex behaviour, i.e. do not print warnings due to glitches
500 // in the headers at runtime. This is not synonym of ignoring warnings as they
501 // will be printed at dictionary generation time.
502 // In order to do this we leverage the diagnostic pragmas and, since there is no
503 // way to express as a pragma the option "-Wno-deprecated" the
504 // _BACKWARD_BACKWARD_WARNING_H macro, used to avoid to go through
505 // backward/backward_warning.h.
506 payloadCode += "#define _BACKWARD_BACKWARD_WARNING_H\n"
507 "// Inline headers\n"+
508 inlinedHeaders + "\n"+
509 (extraIncludes.empty() ? "" : "// Extra includes\n" + extraIncludes + "\n") +
510 "#undef _BACKWARD_BACKWARD_WARNING_H\n";
511
512 // We cannot stream the contents in strings and pass it to
513 // WriteRegistrationSourceImpl because we exceed the std::string::max_size on
514 // Windows.
515 std::vector<std::string> headerArray = {"0"};
517 headerArray = fHeaders;
518 const std::vector<std::string>& includePathArray = fCompI;
519
520 std::string payloadcodeWrapped = "nullptr";
521 if (!fIsInPCH)
522 payloadcodeWrapped = "R\"DICTPAYLOAD(\n" + payloadCode + ")DICTPAYLOAD\"";
523
526 headerArray,
527 includePathArray,
528 fwdDeclStringRAW,
529 fwdDeclnArgsToKeepString,
530 payloadcodeWrapped,
531 headersClassesMapString,
532 extraIncludes,
533 /*HasCxxModule*/false);
534}
535
536////////////////////////////////////////////////////////////////////////////////
537/// Write a header file describing the content of this module
538/// through a series of variables inside the namespace
539/// ROOT::Dict::[DictionaryName]. Each variable is an array of string
540/// literals, with a const char* of 0 being the last element, e.g.
541/// ROOT::Dict::_DictName::arrIncludes[] = { "A.h", "B.h", 0 };
542
543void TModuleGenerator::WriteContentHeader(std::ostream &out) const
544{
545 out << "namespace ROOT { namespace Dict { namespace _"
546 << GetDictionaryName() << "{\n";
547
548 out << "const char* arrIncludes[] = {\n";
549 WriteHeaderArray(out) << "};\n";
550
551 out << "const char* arrIncludePaths[] = {\n";
552 WriteIncludePathArray(out) << "};\n";
553 /*
554 out << "const char* arrDefines[] = {\n";
555 WriteDefinesArray(out) << "};\n";
556
557 out << "const char* arrUndefines[] = {\n";
558 WriteUndefinesArray(out) << "};\n";*/
559
560 out << "} } }" << std::endl;
561}
562
563////////////////////////////////////////////////////////////////////////////////
564/// Return true if the header is found in the include paths
565/// in this case also fill the full path variable with the full path.
566
567bool TModuleGenerator::FindHeader(const std::string &hdrName, std::string &hdrFullPath) const
568{
569 hdrFullPath = hdrName;
570 if (llvm::sys::fs::exists(hdrFullPath))
571 return true;
572 for (auto const &incDir : fCompI) {
573 hdrFullPath = incDir + ROOT::TMetaUtils::GetPathSeparator() + hdrName;
574 if (llvm::sys::fs::exists(hdrFullPath)) {
575 return true;
576 }
577 }
578 clang::Preprocessor &PP = fCI->getPreprocessor();
579 clang::HeaderSearch &HdrSearch = PP.getHeaderSearchInfo();
580 const clang::DirectoryLookup *CurDir = nullptr;
581 if (const clang::FileEntry *hdrFileEntry
582 = HdrSearch.LookupFile(hdrName, clang::SourceLocation(),
583 true /*isAngled*/, nullptr /*FromDir*/, CurDir,
584 clang::ArrayRef<std::pair<const clang::FileEntry*,
585 const clang::DirectoryEntry*>>(),
586 nullptr /*SearchPath*/, nullptr /*RelativePath*/,
587 nullptr /*RequestingModule*/, nullptr/*SuggestedModule*/,
588 nullptr /*IsMapped*/, nullptr /*IsFrameworkFound*/)) {
589 hdrFullPath = hdrFileEntry->getName();
590 return true;
591 }
592
593 return false;
594}
595
596////////////////////////////////////////////////////////////////////////////////
597/// Write a header file pulling in the content of this module
598/// through a series of #defined, #undefs and #includes.
599/// The sequence corrsponds to a rootcling invocation with
600/// -c -DFOO -UBAR header.h
601/// I.e. defines, undefines and finally includes.
602
603void TModuleGenerator::WriteUmbrellaHeader(std::ostream &out) const
604{
605 WritePPDefines(out);
606 WritePPUndefines(out);
607 WritePPIncludes(out);
608}
#define c(i)
Definition: RSha256.hxx:101
int ExtractBufferContent(const std::string &fullHeaderPath, std::string &bufferContent)
int WarnIfPragmaOnceDetected(const std::string &fullHeaderPath, const std::string &headerFileContent)
To be replaced with proper pragma handlers.
static std::pair< std::string, std::string > SplitPPDefine(const std::string &in)
std::vector< std::string > fCompU
void WriteUmbrellaHeader(std::ostream &out) const
Write a header file pulling in the content of this module through a series of #defined,...
std::ostream & WriteHeaderArray(std::ostream &out) const
std::vector< std::pair< std::string, std::string > > StringPairVec_t
std::ostream & WriteStringVec(const std::vector< std::string > &vec, std::ostream &out) const
std::ostream & WriteStringPairVec(const StringPairVec_t &vecP, std::ostream &out) const
void WriteRegistrationSource(std::ostream &out, const std::string &fwdDeclnArgsToKeepString, const std::string &headersClassesMapString, const std::string &fwdDeclsString, const std::string &extraIncludes, bool hasCxxModule) const
ESourceFileKind GetSourceFileKind(const char *filename) const
Check whether the file's extension is compatible with C or C++.
std::ostream & WritePPIncludes(std::ostream &out) const
Write #include "header1.h" #include "header2.h" or, if inlining of headers is requested,...
std::ostream & WriteIncludePathArray(std::ostream &out) const
void WriteContentHeader(std::ostream &out) const
Write a header file describing the content of this module through a series of variables inside the na...
std::vector< std::string > fCompI
std::vector< std::string > fHeaders
std::ostream & WritePPUndefines(std::ostream &out) const
Write #ifdef FOO.
void WriteRegistrationSourceImpl(std::ostream &out, const std::string &dictName, const std::string &demangledDictName, const std::vector< std::string > &headerArray, const std::vector< std::string > &includePathArray, const std::string &fwdDeclStringRAW, const std::string &fwdDeclnArgsToKeepString, const std::string &payloadCodeWrapped, const std::string &headersClassesMapString, const std::string &extraIncludes, bool hasCxxModule) const
const std::string & GetDictionaryName() const
clang::CompilerInstance * fCI
bool FindHeader(const std::string &hdrName, std::string &hdrFullPath) const
Return true if the header is found in the include paths in this case also fill the full path variable...
const std::string & GetDemangledDictionaryName() const
void ParseArgs(const std::vector< std::string > &args)
Parse -I -D -U headers.h SomethingLinkdef.h.
std::ostream & WritePPDefines(std::ostream &out) const
Write #ifndef FOO.
TLine * line
static const std::string pattern("pattern")
void Error(const char *location, const char *va_(fmt),...)
Definition: TClingUtils.h:789
std::string GetModuleFileName(const char *moduleName)
Return the dictionary file name for a module.
void GetCppName(std::string &output, const char *input)
Return (in the argument 'output') a mangled version of the C++ symbol/type (pass as 'input') that can...
bool IsLinkdefFile(const char *filename)
const std::string & GetPathSeparator()
Return the separator suitable for this platform.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Definition: TString.h:850
Definition: civetweb.c:2228