Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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 <algorithm>
39#include <iostream>
40
41using namespace ROOT;
42using namespace clang;
43
44////////////////////////////////////////////////////////////////////////////////
45
48 const std::string &shLibFileName,
50 fCI(CI),
51 fIsPCH(shLibFileName == "allDict.cxx"),
52 fIsInPCH(writeEmptyRootPCM),
53 fInlineInputHeaders(inlineInputHeaders),
54 fDictionaryName(llvm::sys::path::stem(shLibFileName)),
55 fDemangledDictionaryName(llvm::sys::path::stem(shLibFileName)),
56 fModuleDirName(llvm::sys::path::parent_path(shLibFileName)),
57 fErrorCount(0)
58{
59 // Need to resolve _where_ to create the pcm
60 // We default in the lib subdirectory
61 // otherwise we put it in the same directory as the dictionary file (for ACLiC)
62 if (fModuleDirName.empty()) {
63 fModuleDirName = "./";
64 } else {
65 fModuleDirName += "/";
66 }
67
70
71 // Clean the dictionary name from characters which are not accepted in C++
72 std::string tmpName = fDictionaryName;
73 fDictionaryName.clear();
75
76 // .pcm -> .pch
77 if (IsPCH()) fModuleFileName[fModuleFileName.length() - 1] = 'h';
78
79 // Add a random string to the filename to avoid races.
80 auto makeTempFile = [&](const char *suffix) {
81 llvm::SmallString<64> resultPath;
82 std::string pattern = fModuleDirName + fDictionaryName + "%%%%%%%%%%" + suffix;
83 llvm::sys::fs::createUniqueFile(pattern, resultPath); // NOTE: this creates the (empty) file
84 // Return the full buffer, so caller can use `.c_str()` on the temporary.
85 return resultPath;
86 };
87
88 fUmbrellaName = makeTempFile("_dictUmbrella.h").c_str();
89 fContentName = makeTempFile("_dictContent.h").c_str();
90}
91
97
98////////////////////////////////////////////////////////////////////////////////
99/// Check whether the file's extension is compatible with C or C++.
100/// Return whether source, header, Linkdef or nothing.
101
104{
105 if (filename[0] == '-') return kSFKNotC;
106
108 return kSFKLinkdef;
109 }
110
111 const size_t len = strlen(filename);
112 const char *ext = filename + len - 1;
113 while (ext >= filename && *ext != '.') --ext;
114 if (ext < filename || *ext != '.') {
115 // This might still be a system header, let's double check
116 // via the FileManager.
117 clang::Preprocessor &PP = fCI->getPreprocessor();
118 clang::HeaderSearch &HdrSearch = PP.getHeaderSearchInfo();
119 clang::ConstSearchDirIterator *CurDir = nullptr;
120 auto hdrFileEntry
121 = HdrSearch.LookupFile(filename, clang::SourceLocation(),
122 true /*isAngled*/, nullptr /*FromDir*/, CurDir,
123 clang::ArrayRef<std::pair<clang::OptionalFileEntryRef,
124 clang::DirectoryEntryRef>>(),
125 nullptr /*SearchPath*/,/*RelativePath*/ nullptr,
126 nullptr /*RequestingModule*/, nullptr /*SuggestedModule*/,
127 nullptr /*IsMapped*/, nullptr /*IsFrameworkFound*/);
128 if (hdrFileEntry) {
129 return kSFKHeader;
130 }
131 return kSFKNotC;
132 }
133 ++ext;
134 const size_t lenExt = filename + len - ext;
135
137 switch (lenExt) {
138 case 1: {
139 const char last = toupper(filename[len - 1]);
140 if (last == 'H') ret = kSFKHeader;
141 else if (last == 'C') ret = kSFKSource;
142 break;
143 }
144 case 2: {
145 if (filename[len - 2] == 'h' && filename[len - 1] == 'h')
146 ret = kSFKHeader;
147 else if (filename[len - 2] == 'c' && filename[len - 1] == 'c')
148 ret = kSFKSource;
149 break;
150 }
151 case 3: {
152 const char last = filename[len - 1];
153 if ((last == 'x' || last == 'p')
154 && filename[len - 2] == last) {
155 if (filename[len - 3] == 'h') ret = kSFKHeader;
156 else if (filename[len - 3] == 'c') ret = kSFKSource;
157 }
158 }
159 } // switch extension length
160
161 return ret;
162}
163
164
165static
166std::pair<std::string, std::string> SplitPPDefine(const std::string &in)
167{
168 std::string::size_type posEq = in.find('=');
169 // No equal found: define to 1
170 if (posEq == std::string::npos)
171 return std::make_pair(in, "1");
172
173 // Equal found
174 return std::pair<std::string, std::string>
175 (in.substr(0, posEq), in.substr(posEq + 1, std::string::npos));
176}
177
178////////////////////////////////////////////////////////////////////////////////
179/// Parse -I -D -U headers.h SomethingLinkdef.h.
180
181void TModuleGenerator::ParseArgs(const std::vector<std::string> &args)
182{
183 std::vector<std::string> systemIncludePaths;
184 for (size_t iPcmArg = 1 /*skip argv0*/, nPcmArg = args.size();
185 iPcmArg < nPcmArg; ++iPcmArg) {
187 if (sfk == kSFKHeader || sfk == kSFKSource) {
188 fHeaders.push_back(args[iPcmArg]);
189 } else if (sfk == kSFKLinkdef) {
190 fLinkDefFile = args[iPcmArg];
191 } else if (sfk == kSFKNotC && args[iPcmArg][0] == '-') {
192 switch (args[iPcmArg][1]) {
193 case 'i':
194 if (args[iPcmArg].find("-isystem") != std::string::npos) {
195 if (args[iPcmArg].size() == 8)
196 systemIncludePaths.push_back(args[++iPcmArg]);
197 else {
198 auto pos = 9; // start after -isystem
199 while (args[iPcmArg][pos] == ' ')
200 pos++;
201 systemIncludePaths.push_back(args[iPcmArg].substr(pos));
202 }
203 }
204 break;
205 case 'I':
206 if (args[iPcmArg] != "-I." && args[iPcmArg] != "-Iinclude") {
207 fCompI.push_back(args[iPcmArg].c_str() + 2);
208 }
209 break;
210 case 'D':
211 if (args[iPcmArg] != "-DTRUE=1" && args[iPcmArg] != "-DFALSE=0" && args[iPcmArg] != "-DG__NOCINTDLL") {
212 fCompD.push_back(SplitPPDefine(args[iPcmArg].c_str() + 2));
213 }
214 break;
215 case 'U': fCompU.push_back(args[iPcmArg].c_str() + 2); break;
216 }
217 }
218 }
219
220 // System includes have lowest priority, so we move them to the end:
221 std::move(systemIncludePaths.begin(), systemIncludePaths.end(), std::back_inserter(fCompI));
222 fCompI.erase(std::unique(fCompI.begin(), fCompI.end()), fCompI.end());
223}
224
225////////////////////////////////////////////////////////////////////////////////
226/// Write
227/// `#ifndef FOO`
228/// `# define FOO=bar`
229/// `#endif`
230
231std::ostream &TModuleGenerator::WritePPDefines(std::ostream &out) const
232{
233 for (auto const & strPair : fCompD) {
234 std::string cppname(strPair.first);
235 size_t pos = cppname.find('(');
236 if (pos != std::string::npos) cppname.erase(pos);
237 out << "#ifndef " << cppname << "\n"
238 " #define " << strPair.first;
239 out << " " << strPair.second;
240 out << "\n"
241 "#endif\n";
242 }
243 out << std::endl;
244 return out;
245}
246
247////////////////////////////////////////////////////////////////////////////////
248/// Write
249/// `#ifdef FOO`
250/// `# undef FOO`
251/// `#endif`
252
253std::ostream &TModuleGenerator::WritePPUndefines(std::ostream &out) const
254{
255 for (auto const & undef : fCompU) {
256 out << "#ifdef " << undef << "\n"
257 " #undef " << undef << "\n"
258 "#endif\n";
259 }
260 out << std::endl;
261 return out;
262}
263
264////////////////////////////////////////////////////////////////////////////////
265/// To be replaced with proper pragma handlers.
266
268 const std::string& headerFileContent)
269{
270 std::istringstream headerFile(headerFileContent);
271 std::string line;
272 while(std::getline(headerFile,line)){
273 llvm::StringRef lineRef (line);
274 auto trimmedLineRef = lineRef.trim();
275 if (trimmedLineRef.starts_with("#pragma") &&
276 (trimmedLineRef.ends_with(" once") || trimmedLineRef.ends_with("\tonce"))) {
277 std::cerr << "Error: #pragma once directive detected in header file "
279 << " which was requested to be inlined.\n";
280 return 1;
281 }
282 }
283 return 0;
284}
285
286////////////////////////////////////////////////////////////////////////////////
287
288int ExtractBufferContent(const std::string& fullHeaderPath, std::string& bufferContent)
289{
290 std::ifstream buffer(fullHeaderPath);
291 bufferContent = std::string((std::istreambuf_iterator<char>(buffer)),
292 std::istreambuf_iterator<char>());
293
295}
296
297////////////////////////////////////////////////////////////////////////////////
298/// Write
299/// `#include "header1.h"`
300/// `#include "header2.h"`
301/// or, if inlining of headers is requested, dump the content of the files.
302
303std::ostream &TModuleGenerator::WritePPIncludes(std::ostream &out) const
304{
305 std::string fullHeaderPath;
306 for (auto const & incl : fHeaders) {
309 if (!headerFound){
310 ROOT::TMetaUtils::Error(nullptr, "Cannot find header %s: cannot inline it.\n", fullHeaderPath.c_str());
311 continue;
312 }
313
314 std::string bufferContent;
316
317 out << bufferContent << std::endl;
318 } else {
319 out << "#include \"" << incl << "\"\n";
320 }
321 }
322 out << std::endl;
323 return out;
324}
325
326////////////////////////////////////////////////////////////////////////////////
327
328std::ostream &TModuleGenerator::WriteStringVec(const std::vector<std::string> &vec,
329 std::ostream &out) const
330{
331 for (auto const & theStr : vec) {
332 out << "\"" << theStr << "\",\n";
333 }
334 out << "nullptr" << std::endl;
335 return out;
336}
337
338////////////////////////////////////////////////////////////////////////////////
339
341 std::ostream &out) const
342{
343 for (auto const & strPair : vec) {
344 out << "\"" << strPair.first;
345 if (!strPair.second.empty()) {
346 out << "=";
347 // Need to escape the embedded quotes.
348 for (const char *c = strPair.second.c_str(); *c != '\0'; ++c) {
349 if (*c == '"') {
350 out << "\\\"";
351 } else {
352 out << *c;
353 }
354 }
355 }
356 out << "\",\n";
357 }
358 out << "nullptr" << std::endl;
359 return out;
360}
361
362
364 const std::string &dictName,
365 const std::string &demangledDictName,
366 const std::vector<std::string> &headerArray,
367 const std::vector<std::string> &includePathArray,
368 const std::string &fwdDeclStringRAW,
369 const std::string &fwdDeclnArgsToKeepString,
370 const std::string &payloadCodeWrapped,
371 const std::string &headersClassesMapString,
372 const std::string &extraIncludes,
373 bool hasCxxModule) const
374{
375 // Dictionary initialization code for loading the module
376 out << "namespace {\n"
377 " void TriggerDictionaryInitialization_" << dictName << "_Impl() {\n"
378 " static const char* headers[] = {\n";
379 WriteStringVec(headerArray, out) << " };\n";
380 out << " static const char* includePaths[] = {\n";
382 << " };\n";
383
384 out << " static const char* fwdDeclCode = " << fwdDeclStringRAW << ";\n"
385 << " static const char* payloadCode = " << payloadCodeWrapped << ";\n";
386 // classesHeaders may depen on payloadCode
387 out << " static const char* classesHeaders[] = {\n"
389 << "\n};\n";
390 out << " static bool isInitialized = false;\n"
391 " if (!isInitialized) {\n"
392 " TROOT::RegisterModule(\"" << demangledDictName << "\",\n"
393 " headers, includePaths, payloadCode, fwdDeclCode,\n"
394 " TriggerDictionaryInitialization_" << dictName << "_Impl, "
395 << fwdDeclnArgsToKeepString << ", classesHeaders, "
396 << (hasCxxModule ? "/*hasCxxModule*/true" : "/*hasCxxModule*/false")
397 << ");\n"
398 " isInitialized = true;\n"
399 " }\n"
400 " }\n"
401 " static struct DictInit {\n"
402 " DictInit() {\n"
403 " TriggerDictionaryInitialization_" << dictName << "_Impl();\n"
404 " }\n"
405 " } __TheDictionaryInitializer;\n"
406 "}\n"
407 "void TriggerDictionaryInitialization_" << dictName << "() {\n"
408 " TriggerDictionaryInitialization_" << dictName << "_Impl();\n"
409 "}\n";
410}
411
412////////////////////////////////////////////////////////////////////////////////
413
415 const std::string &headersClassesMapString,
416 const std::string &fwdDeclString, const std::string &extraIncludes, bool hasCxxModule) const
417{
418 if (hasCxxModule) {
419 std::string emptyStr = "\"\"";
422 /*HasCxxModule*/ true);
423 return;
424 }
425
427#ifdef R__WIN32
428 // Visual sudio has a limitation of 2048 characters max in raw strings, so split
429 // the potentially huge DICTFWDDCLS raw string into multiple smaller ones
430 constexpr char from[] = "\n";
431 constexpr char to[] = "\n)DICTFWDDCLS\"\nR\"DICTFWDDCLS(";
432 size_t start_pos = 0;
433 while ((start_pos = fwdDeclStringSanitized.find(from, start_pos)) != std::string::npos) {
434 if (fwdDeclStringSanitized.find(from, start_pos + 1) == std::string::npos) // skip the last
435 break;
436 if ((fwdDeclStringSanitized.at(start_pos + 1) == '}') || (fwdDeclStringSanitized.at(start_pos + 1) == '\n'))
437 start_pos += 2;
438 else {
439 fwdDeclStringSanitized.replace(start_pos, strlen(from), to);
440 start_pos += strlen(to); // In case 'to' contains 'from', like replacing 'x' with 'yx'
441 }
442 }
443#endif
444 std::string fwdDeclStringRAW;
445 if ("nullptr" == fwdDeclStringSanitized || "\"\"" == fwdDeclStringSanitized) {
447 } else {
448 fwdDeclStringRAW = "R\"DICTFWDDCLS(\n";
449 fwdDeclStringRAW += "#line 1 \"";
450 fwdDeclStringRAW += fDictionaryName +" dictionary forward declarations' payload\"\n";
452 fwdDeclStringRAW += ")DICTFWDDCLS\"";
453 }
454
455 if (fIsInPCH)
456 fwdDeclStringRAW = "nullptr";
457
458 std::string payloadCode;
459
460 // Increase the value of the diagnostics pointing out from which
461 // dictionary this payload comes from in case of errors
462 payloadCode += "#line 1 \"";
463 payloadCode += fDictionaryName +" dictionary payload\"\n";
464
465 // Add defines and undefines to the payloadCode
466 std::ostringstream definesAndUndefines;
467 // Anticipate the undefines.
468 // Suppose to have a namespace called "declarations" used in R5 for template
469 // instantiations in the header given to genreflex.
470 // Now, in this namespace, objects with some names, typically dummy, will be
471 // present.
472 // If you give such headers to cling to parse, problems will occour, as the
473 // names appear multiple times. One possible solution is to get out of this
474 // with preprocessor defines given to genreflex, redefining "declarations"
475 // to a hash or <project>_<package> via the build system.
479
480 // If necessary, inline the headers
481 std::string hdrFullPath;
482 std::string inlinedHeaders;
483
484 auto findAndAddToInlineHeaders = [&](const std::string& hdrName) {
486 if (!headerFound) {
487 ROOT::TMetaUtils::Error(nullptr, "Cannot find header %s: cannot inline it.\n", hdrName.c_str());
488 } else {
489 std::ifstream headerFile(hdrFullPath.c_str());
490 const std::string headerFileAsStr((std::istreambuf_iterator<char>(headerFile)),
491 std::istreambuf_iterator<char>());
493 }
494 };
495
497 for (auto const & hdrName : fHeaders) {
499 }
500
501 } else {
502 // Now, if not, just #include them in the payload except for the linkdef
503 // file, if any.
504 for (auto & hdrName : fHeaders) {
505 inlinedHeaders += "#include \"" + hdrName + "\"\n";
506 }
507 }
508
509 if (0 != fLinkDefFile.size() && !fIsPCH) {
511 }
512
513 // Recover old genreflex behaviour, i.e. do not print warnings due to glitches
514 // in the headers at runtime. This is not synonym of ignoring warnings as they
515 // will be printed at dictionary generation time.
516 // In order to do this we leverage the diagnostic pragmas and, since there is no
517 // way to express as a pragma the option "-Wno-deprecated" the
518 // _BACKWARD_BACKWARD_WARNING_H macro, used to avoid to go through
519 // backward/backward_warning.h.
520 payloadCode += "#define _BACKWARD_BACKWARD_WARNING_H\n"
521 "// Inline headers\n"+
522 inlinedHeaders + "\n"+
523 (extraIncludes.empty() ? "" : "// Extra includes\n" + extraIncludes + "\n") +
524 "#undef _BACKWARD_BACKWARD_WARNING_H\n";
525
526 // We cannot stream the contents in strings and pass it to
527 // WriteRegistrationSourceImpl because we exceed the std::string::max_size on
528 // Windows.
529 std::vector<std::string> headerArray = {"0"};
532 const std::vector<std::string>& includePathArray = fCompI;
533
534 std::string payloadcodeWrapped = "nullptr";
535 if (!fIsInPCH)
536 payloadcodeWrapped = "R\"DICTPAYLOAD(\n" + payloadCode + ")DICTPAYLOAD\"";
537
547 /*HasCxxModule*/false);
548}
549
550////////////////////////////////////////////////////////////////////////////////
551/// Write a header file describing the content of this module
552/// through a series of variables inside the namespace
553/// ROOT::Dict::[DictionaryName]. Each variable is an array of string
554/// literals, with a const char* of 0 being the last element, e.g.
555/// ROOT::Dict::_DictName::arrIncludes[] = { "A.h", "B.h", 0 };
556
557void TModuleGenerator::WriteContentHeader(std::ostream &out) const
558{
559 out << "namespace ROOT { namespace Dict { namespace _"
560 << GetDictionaryName() << "{\n";
561
562 out << "const char* arrIncludes[] = {\n";
563 WriteHeaderArray(out) << "};\n";
564
565 out << "const char* arrIncludePaths[] = {\n";
566 WriteIncludePathArray(out) << "};\n";
567 /*
568 out << "const char* arrDefines[] = {\n";
569 WriteDefinesArray(out) << "};\n";
570
571 out << "const char* arrUndefines[] = {\n";
572 WriteUndefinesArray(out) << "};\n";*/
573
574 out << "} } }" << std::endl;
575}
576
577////////////////////////////////////////////////////////////////////////////////
578/// Return true if the header is found in the include paths
579/// in this case also fill the full path variable with the full path.
580
581bool TModuleGenerator::FindHeader(const std::string &hdrName, std::string &hdrFullPath) const
582{
584 if (llvm::sys::fs::exists(hdrFullPath))
585 return true;
586 for (auto const &incDir : fCompI) {
588 if (llvm::sys::fs::exists(hdrFullPath)) {
589 return true;
590 }
591 }
592 clang::Preprocessor &PP = fCI->getPreprocessor();
593 clang::HeaderSearch &HdrSearch = PP.getHeaderSearchInfo();
594 clang::ConstSearchDirIterator *CurDir = nullptr;
595 if (auto hdrFileEntry
596 = HdrSearch.LookupFile(hdrName, clang::SourceLocation(),
597 true /*isAngled*/, nullptr /*FromDir*/, CurDir,
598 clang::ArrayRef<std::pair<clang::OptionalFileEntryRef,
599 clang::DirectoryEntryRef>>(),
600 nullptr /*SearchPath*/, nullptr /*RelativePath*/,
601 nullptr /*RequestingModule*/, nullptr/*SuggestedModule*/,
602 nullptr /*IsMapped*/, nullptr /*IsFrameworkFound*/)) {
603 hdrFullPath = hdrFileEntry->getName().str();
604 return true;
605 }
606
607 return false;
608}
609
610////////////////////////////////////////////////////////////////////////////////
611/// Write a header file pulling in the content of this module
612/// through a series of `#defined`, `#undefs` and `#includes`.
613/// The sequence corrsponds to a rootcling invocation with
614/// -c -DFOO -UBAR header.h
615/// I.e. defines, undefines and finally includes.
616
617void TModuleGenerator::WriteUmbrellaHeader(std::ostream &out) const
618{
619 WritePPDefines(out);
620 WritePPUndefines(out);
621 WritePPIncludes(out);
622}
#define c(i)
Definition RSha256.hxx:101
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
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)
const_iterator begin() const
const_iterator end() const
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,...
TModuleGenerator(clang::CompilerInstance *CI, bool inlineHeader, const std::string &shLibFileName, bool isInPCH)
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 # undef FOO #endif
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 # define FOO=bar #endif
TLine * line
void Error(const char *location, const char *fmt,...)
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 valid name of the C++ symbol/type (pass as 'input') that can be u...
bool IsLinkdefFile(const char *filename)
const std::string & GetPathSeparator()
Return the separator suitable for this platform.
Namespace for new ROOT classes and functions.