1*5971e316Smrg /*
2*5971e316Smrg * Copyright 2011 Sven Verdoolaege. All rights reserved.
3*5971e316Smrg *
4*5971e316Smrg * Redistribution and use in source and binary forms, with or without
5*5971e316Smrg * modification, are permitted provided that the following conditions
6*5971e316Smrg * are met:
7*5971e316Smrg *
8*5971e316Smrg * 1. Redistributions of source code must retain the above copyright
9*5971e316Smrg * notice, this list of conditions and the following disclaimer.
10*5971e316Smrg *
11*5971e316Smrg * 2. Redistributions in binary form must reproduce the above
12*5971e316Smrg * copyright notice, this list of conditions and the following
13*5971e316Smrg * disclaimer in the documentation and/or other materials provided
14*5971e316Smrg * with the distribution.
15*5971e316Smrg *
16*5971e316Smrg * THIS SOFTWARE IS PROVIDED BY SVEN VERDOOLAEGE ''AS IS'' AND ANY
17*5971e316Smrg * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*5971e316Smrg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19*5971e316Smrg * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SVEN VERDOOLAEGE OR
20*5971e316Smrg * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21*5971e316Smrg * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22*5971e316Smrg * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23*5971e316Smrg * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24*5971e316Smrg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25*5971e316Smrg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26*5971e316Smrg * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*5971e316Smrg *
28*5971e316Smrg * The views and conclusions contained in the software and documentation
29*5971e316Smrg * are those of the authors and should not be interpreted as
30*5971e316Smrg * representing official policies, either expressed or implied, of
31*5971e316Smrg * Sven Verdoolaege.
32*5971e316Smrg */
33*5971e316Smrg
34*5971e316Smrg #include "isl_config.h"
35*5971e316Smrg #undef PACKAGE
36*5971e316Smrg
37*5971e316Smrg #include <assert.h>
38*5971e316Smrg #include <iostream>
39*5971e316Smrg #include <stdlib.h>
40*5971e316Smrg #ifdef HAVE_ADT_OWNINGPTR_H
41*5971e316Smrg #include <llvm/ADT/OwningPtr.h>
42*5971e316Smrg #else
43*5971e316Smrg #include <memory>
44*5971e316Smrg #endif
45*5971e316Smrg #ifdef HAVE_LLVM_OPTION_ARG_H
46*5971e316Smrg #include <llvm/Option/Arg.h>
47*5971e316Smrg #endif
48*5971e316Smrg #include <llvm/Support/raw_ostream.h>
49*5971e316Smrg #include <llvm/Support/CommandLine.h>
50*5971e316Smrg #ifdef HAVE_TARGETPARSER_HOST_H
51*5971e316Smrg #include <llvm/TargetParser/Host.h>
52*5971e316Smrg #else
53*5971e316Smrg #include <llvm/Support/Host.h>
54*5971e316Smrg #endif
55*5971e316Smrg #include <llvm/Support/ManagedStatic.h>
56*5971e316Smrg #include <clang/AST/ASTContext.h>
57*5971e316Smrg #include <clang/AST/ASTConsumer.h>
58*5971e316Smrg #include <clang/Basic/Builtins.h>
59*5971e316Smrg #include <clang/Basic/FileSystemOptions.h>
60*5971e316Smrg #include <clang/Basic/FileManager.h>
61*5971e316Smrg #include <clang/Basic/TargetOptions.h>
62*5971e316Smrg #include <clang/Basic/TargetInfo.h>
63*5971e316Smrg #include <clang/Basic/Version.h>
64*5971e316Smrg #include <clang/Driver/Compilation.h>
65*5971e316Smrg #include <clang/Driver/Driver.h>
66*5971e316Smrg #include <clang/Driver/Tool.h>
67*5971e316Smrg #include <clang/Frontend/CompilerInstance.h>
68*5971e316Smrg #include <clang/Frontend/CompilerInvocation.h>
69*5971e316Smrg #ifdef HAVE_BASIC_DIAGNOSTICOPTIONS_H
70*5971e316Smrg #include <clang/Basic/DiagnosticOptions.h>
71*5971e316Smrg #else
72*5971e316Smrg #include <clang/Frontend/DiagnosticOptions.h>
73*5971e316Smrg #endif
74*5971e316Smrg #include <clang/Frontend/TextDiagnosticPrinter.h>
75*5971e316Smrg #include <clang/Frontend/Utils.h>
76*5971e316Smrg #include <clang/Lex/HeaderSearch.h>
77*5971e316Smrg #ifdef HAVE_LEX_PREPROCESSOROPTIONS_H
78*5971e316Smrg #include <clang/Lex/PreprocessorOptions.h>
79*5971e316Smrg #else
80*5971e316Smrg #include <clang/Frontend/PreprocessorOptions.h>
81*5971e316Smrg #endif
82*5971e316Smrg #include <clang/Lex/Preprocessor.h>
83*5971e316Smrg #include <clang/Parse/ParseAST.h>
84*5971e316Smrg #include <clang/Sema/Sema.h>
85*5971e316Smrg
86*5971e316Smrg #include "extract_interface.h"
87*5971e316Smrg #include "generator.h"
88*5971e316Smrg #include "python.h"
89*5971e316Smrg #include "plain_cpp.h"
90*5971e316Smrg #include "cpp_conversion.h"
91*5971e316Smrg #include "template_cpp.h"
92*5971e316Smrg
93*5971e316Smrg using namespace std;
94*5971e316Smrg using namespace clang;
95*5971e316Smrg using namespace clang::driver;
96*5971e316Smrg #ifdef HAVE_LLVM_OPTION_ARG_H
97*5971e316Smrg using namespace llvm::opt;
98*5971e316Smrg #endif
99*5971e316Smrg
100*5971e316Smrg #ifdef HAVE_ADT_OWNINGPTR_H
101*5971e316Smrg #define unique_ptr llvm::OwningPtr
102*5971e316Smrg #endif
103*5971e316Smrg
104*5971e316Smrg static llvm::cl::opt<string> InputFilename(llvm::cl::Positional,
105*5971e316Smrg llvm::cl::Required, llvm::cl::desc("<input file>"));
106*5971e316Smrg static llvm::cl::list<string> Includes("I",
107*5971e316Smrg llvm::cl::desc("Header search path"),
108*5971e316Smrg llvm::cl::value_desc("path"), llvm::cl::Prefix);
109*5971e316Smrg
110*5971e316Smrg static llvm::cl::opt<string> OutputLanguage(llvm::cl::Required,
111*5971e316Smrg llvm::cl::ValueRequired, "language",
112*5971e316Smrg llvm::cl::desc("Bindings to generate"),
113*5971e316Smrg llvm::cl::value_desc("name"));
114*5971e316Smrg
115*5971e316Smrg static const char *ResourceDir =
116*5971e316Smrg CLANG_PREFIX "/lib/clang/" CLANG_VERSION_STRING;
117*5971e316Smrg
118*5971e316Smrg /* Does decl have an attribute of the following form?
119*5971e316Smrg *
120*5971e316Smrg * __attribute__((annotate("name")))
121*5971e316Smrg */
has_annotation(Decl * decl,const char * name)122*5971e316Smrg bool has_annotation(Decl *decl, const char *name)
123*5971e316Smrg {
124*5971e316Smrg if (!decl->hasAttrs())
125*5971e316Smrg return false;
126*5971e316Smrg
127*5971e316Smrg AttrVec attrs = decl->getAttrs();
128*5971e316Smrg for (AttrVec::const_iterator i = attrs.begin() ; i != attrs.end(); ++i) {
129*5971e316Smrg const AnnotateAttr *ann = dyn_cast<AnnotateAttr>(*i);
130*5971e316Smrg if (!ann)
131*5971e316Smrg continue;
132*5971e316Smrg if (ann->getAnnotation().str() == name)
133*5971e316Smrg return true;
134*5971e316Smrg }
135*5971e316Smrg
136*5971e316Smrg return false;
137*5971e316Smrg }
138*5971e316Smrg
139*5971e316Smrg /* Is decl marked as exported?
140*5971e316Smrg */
is_exported(Decl * decl)141*5971e316Smrg static bool is_exported(Decl *decl)
142*5971e316Smrg {
143*5971e316Smrg return has_annotation(decl, "isl_export");
144*5971e316Smrg }
145*5971e316Smrg
146*5971e316Smrg /* Collect all types and functions that are annotated "isl_export"
147*5971e316Smrg * in "exported_types" and "exported_function". Collect all function
148*5971e316Smrg * declarations in "functions".
149*5971e316Smrg *
150*5971e316Smrg * We currently only consider single declarations.
151*5971e316Smrg */
152*5971e316Smrg struct MyASTConsumer : public ASTConsumer {
153*5971e316Smrg set<RecordDecl *> exported_types;
154*5971e316Smrg set<FunctionDecl *> exported_functions;
155*5971e316Smrg set<FunctionDecl *> functions;
156*5971e316Smrg
HandleTopLevelDeclMyASTConsumer157*5971e316Smrg virtual HandleTopLevelDeclReturn HandleTopLevelDecl(DeclGroupRef D) {
158*5971e316Smrg Decl *decl;
159*5971e316Smrg
160*5971e316Smrg if (!D.isSingleDecl())
161*5971e316Smrg return HandleTopLevelDeclContinue;
162*5971e316Smrg decl = D.getSingleDecl();
163*5971e316Smrg if (isa<FunctionDecl>(decl))
164*5971e316Smrg functions.insert(cast<FunctionDecl>(decl));
165*5971e316Smrg if (!is_exported(decl))
166*5971e316Smrg return HandleTopLevelDeclContinue;
167*5971e316Smrg switch (decl->getKind()) {
168*5971e316Smrg case Decl::Record:
169*5971e316Smrg exported_types.insert(cast<RecordDecl>(decl));
170*5971e316Smrg break;
171*5971e316Smrg case Decl::Function:
172*5971e316Smrg exported_functions.insert(cast<FunctionDecl>(decl));
173*5971e316Smrg break;
174*5971e316Smrg default:
175*5971e316Smrg break;
176*5971e316Smrg }
177*5971e316Smrg return HandleTopLevelDeclContinue;
178*5971e316Smrg }
179*5971e316Smrg };
180*5971e316Smrg
181*5971e316Smrg #ifdef USE_ARRAYREF
182*5971e316Smrg
183*5971e316Smrg #ifdef HAVE_CXXISPRODUCTION
construct_driver(const char * binary,DiagnosticsEngine & Diags)184*5971e316Smrg static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags)
185*5971e316Smrg {
186*5971e316Smrg return new Driver(binary, llvm::sys::getDefaultTargetTriple(),
187*5971e316Smrg "", false, false, Diags);
188*5971e316Smrg }
189*5971e316Smrg #elif defined(HAVE_ISPRODUCTION)
construct_driver(const char * binary,DiagnosticsEngine & Diags)190*5971e316Smrg static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags)
191*5971e316Smrg {
192*5971e316Smrg return new Driver(binary, llvm::sys::getDefaultTargetTriple(),
193*5971e316Smrg "", false, Diags);
194*5971e316Smrg }
195*5971e316Smrg #elif defined(DRIVER_CTOR_TAKES_DEFAULTIMAGENAME)
construct_driver(const char * binary,DiagnosticsEngine & Diags)196*5971e316Smrg static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags)
197*5971e316Smrg {
198*5971e316Smrg return new Driver(binary, llvm::sys::getDefaultTargetTriple(),
199*5971e316Smrg "", Diags);
200*5971e316Smrg }
201*5971e316Smrg #else
construct_driver(const char * binary,DiagnosticsEngine & Diags)202*5971e316Smrg static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags)
203*5971e316Smrg {
204*5971e316Smrg return new Driver(binary, llvm::sys::getDefaultTargetTriple(), Diags);
205*5971e316Smrg }
206*5971e316Smrg #endif
207*5971e316Smrg
208*5971e316Smrg namespace clang { namespace driver { class Job; } }
209*5971e316Smrg
210*5971e316Smrg /* Clang changed its API from 3.5 to 3.6 and once more in 3.7.
211*5971e316Smrg * We fix this with a simple overloaded function here.
212*5971e316Smrg */
213*5971e316Smrg struct ClangAPI {
commandClangAPI214*5971e316Smrg static Job *command(Job *J) { return J; }
commandClangAPI215*5971e316Smrg static Job *command(Job &J) { return &J; }
commandClangAPI216*5971e316Smrg static Command *command(Command &C) { return &C; }
217*5971e316Smrg };
218*5971e316Smrg
219*5971e316Smrg #ifdef CREATE_FROM_ARGS_TAKES_ARRAYREF
220*5971e316Smrg
221*5971e316Smrg /* Call CompilerInvocation::CreateFromArgs with the right arguments.
222*5971e316Smrg * In this case, an ArrayRef<const char *>.
223*5971e316Smrg */
create_from_args(CompilerInvocation & invocation,const ArgStringList * args,DiagnosticsEngine & Diags)224*5971e316Smrg static void create_from_args(CompilerInvocation &invocation,
225*5971e316Smrg const ArgStringList *args, DiagnosticsEngine &Diags)
226*5971e316Smrg {
227*5971e316Smrg CompilerInvocation::CreateFromArgs(invocation, *args, Diags);
228*5971e316Smrg }
229*5971e316Smrg
230*5971e316Smrg #else
231*5971e316Smrg
232*5971e316Smrg /* Call CompilerInvocation::CreateFromArgs with the right arguments.
233*5971e316Smrg * In this case, two "const char *" pointers.
234*5971e316Smrg */
create_from_args(CompilerInvocation & invocation,const ArgStringList * args,DiagnosticsEngine & Diags)235*5971e316Smrg static void create_from_args(CompilerInvocation &invocation,
236*5971e316Smrg const ArgStringList *args, DiagnosticsEngine &Diags)
237*5971e316Smrg {
238*5971e316Smrg CompilerInvocation::CreateFromArgs(invocation, args->data() + 1,
239*5971e316Smrg args->data() + args->size(),
240*5971e316Smrg Diags);
241*5971e316Smrg }
242*5971e316Smrg
243*5971e316Smrg #endif
244*5971e316Smrg
245*5971e316Smrg #ifdef CLANG_SYSROOT
246*5971e316Smrg /* Set sysroot if required.
247*5971e316Smrg *
248*5971e316Smrg * If CLANG_SYSROOT is defined, then set it to this value.
249*5971e316Smrg */
set_sysroot(ArgStringList & args)250*5971e316Smrg static void set_sysroot(ArgStringList &args)
251*5971e316Smrg {
252*5971e316Smrg args.push_back("-isysroot");
253*5971e316Smrg args.push_back(CLANG_SYSROOT);
254*5971e316Smrg }
255*5971e316Smrg #else
256*5971e316Smrg /* Set sysroot if required.
257*5971e316Smrg *
258*5971e316Smrg * If CLANG_SYSROOT is not defined, then it does not need to be set.
259*5971e316Smrg */
set_sysroot(ArgStringList & args)260*5971e316Smrg static void set_sysroot(ArgStringList &args)
261*5971e316Smrg {
262*5971e316Smrg }
263*5971e316Smrg #endif
264*5971e316Smrg
265*5971e316Smrg /* Create a CompilerInvocation object that stores the command line
266*5971e316Smrg * arguments constructed by the driver.
267*5971e316Smrg * The arguments are mainly useful for setting up the system include
268*5971e316Smrg * paths on newer clangs and on some platforms.
269*5971e316Smrg */
construct_invocation(const char * filename,DiagnosticsEngine & Diags)270*5971e316Smrg static CompilerInvocation *construct_invocation(const char *filename,
271*5971e316Smrg DiagnosticsEngine &Diags)
272*5971e316Smrg {
273*5971e316Smrg const char *binary = CLANG_PREFIX"/bin/clang";
274*5971e316Smrg const unique_ptr<Driver> driver(construct_driver(binary, Diags));
275*5971e316Smrg std::vector<const char *> Argv;
276*5971e316Smrg Argv.push_back(binary);
277*5971e316Smrg Argv.push_back(filename);
278*5971e316Smrg const unique_ptr<Compilation> compilation(
279*5971e316Smrg driver->BuildCompilation(llvm::ArrayRef<const char *>(Argv)));
280*5971e316Smrg JobList &Jobs = compilation->getJobs();
281*5971e316Smrg
282*5971e316Smrg Command *cmd = cast<Command>(ClangAPI::command(*Jobs.begin()));
283*5971e316Smrg if (strcmp(cmd->getCreator().getName(), "clang"))
284*5971e316Smrg return NULL;
285*5971e316Smrg
286*5971e316Smrg ArgStringList args = cmd->getArguments();
287*5971e316Smrg set_sysroot(args);
288*5971e316Smrg
289*5971e316Smrg CompilerInvocation *invocation = new CompilerInvocation;
290*5971e316Smrg create_from_args(*invocation, &args, Diags);
291*5971e316Smrg return invocation;
292*5971e316Smrg }
293*5971e316Smrg
294*5971e316Smrg #else
295*5971e316Smrg
construct_invocation(const char * filename,DiagnosticsEngine & Diags)296*5971e316Smrg static CompilerInvocation *construct_invocation(const char *filename,
297*5971e316Smrg DiagnosticsEngine &Diags)
298*5971e316Smrg {
299*5971e316Smrg return NULL;
300*5971e316Smrg }
301*5971e316Smrg
302*5971e316Smrg #endif
303*5971e316Smrg
304*5971e316Smrg #ifdef HAVE_BASIC_DIAGNOSTICOPTIONS_H
305*5971e316Smrg
construct_printer(void)306*5971e316Smrg static TextDiagnosticPrinter *construct_printer(void)
307*5971e316Smrg {
308*5971e316Smrg return new TextDiagnosticPrinter(llvm::errs(), new DiagnosticOptions());
309*5971e316Smrg }
310*5971e316Smrg
311*5971e316Smrg #else
312*5971e316Smrg
construct_printer(void)313*5971e316Smrg static TextDiagnosticPrinter *construct_printer(void)
314*5971e316Smrg {
315*5971e316Smrg DiagnosticOptions DO;
316*5971e316Smrg return new TextDiagnosticPrinter(llvm::errs(), DO);
317*5971e316Smrg }
318*5971e316Smrg
319*5971e316Smrg #endif
320*5971e316Smrg
321*5971e316Smrg #ifdef CREATETARGETINFO_TAKES_SHARED_PTR
322*5971e316Smrg
create_target_info(CompilerInstance * Clang,DiagnosticsEngine & Diags)323*5971e316Smrg static TargetInfo *create_target_info(CompilerInstance *Clang,
324*5971e316Smrg DiagnosticsEngine &Diags)
325*5971e316Smrg {
326*5971e316Smrg shared_ptr<TargetOptions> TO = Clang->getInvocation().TargetOpts;
327*5971e316Smrg TO->Triple = llvm::sys::getDefaultTargetTriple();
328*5971e316Smrg return TargetInfo::CreateTargetInfo(Diags, TO);
329*5971e316Smrg }
330*5971e316Smrg
331*5971e316Smrg #elif defined(CREATETARGETINFO_TAKES_POINTER)
332*5971e316Smrg
create_target_info(CompilerInstance * Clang,DiagnosticsEngine & Diags)333*5971e316Smrg static TargetInfo *create_target_info(CompilerInstance *Clang,
334*5971e316Smrg DiagnosticsEngine &Diags)
335*5971e316Smrg {
336*5971e316Smrg TargetOptions &TO = Clang->getTargetOpts();
337*5971e316Smrg TO.Triple = llvm::sys::getDefaultTargetTriple();
338*5971e316Smrg return TargetInfo::CreateTargetInfo(Diags, &TO);
339*5971e316Smrg }
340*5971e316Smrg
341*5971e316Smrg #else
342*5971e316Smrg
create_target_info(CompilerInstance * Clang,DiagnosticsEngine & Diags)343*5971e316Smrg static TargetInfo *create_target_info(CompilerInstance *Clang,
344*5971e316Smrg DiagnosticsEngine &Diags)
345*5971e316Smrg {
346*5971e316Smrg TargetOptions &TO = Clang->getTargetOpts();
347*5971e316Smrg TO.Triple = llvm::sys::getDefaultTargetTriple();
348*5971e316Smrg return TargetInfo::CreateTargetInfo(Diags, TO);
349*5971e316Smrg }
350*5971e316Smrg
351*5971e316Smrg #endif
352*5971e316Smrg
353*5971e316Smrg #ifdef CREATEDIAGNOSTICS_TAKES_ARG
354*5971e316Smrg
create_diagnostics(CompilerInstance * Clang)355*5971e316Smrg static void create_diagnostics(CompilerInstance *Clang)
356*5971e316Smrg {
357*5971e316Smrg Clang->createDiagnostics(0, NULL, construct_printer());
358*5971e316Smrg }
359*5971e316Smrg
360*5971e316Smrg #else
361*5971e316Smrg
create_diagnostics(CompilerInstance * Clang)362*5971e316Smrg static void create_diagnostics(CompilerInstance *Clang)
363*5971e316Smrg {
364*5971e316Smrg Clang->createDiagnostics(construct_printer());
365*5971e316Smrg }
366*5971e316Smrg
367*5971e316Smrg #endif
368*5971e316Smrg
369*5971e316Smrg #ifdef CREATEPREPROCESSOR_TAKES_TUKIND
370*5971e316Smrg
create_preprocessor(CompilerInstance * Clang)371*5971e316Smrg static void create_preprocessor(CompilerInstance *Clang)
372*5971e316Smrg {
373*5971e316Smrg Clang->createPreprocessor(TU_Complete);
374*5971e316Smrg }
375*5971e316Smrg
376*5971e316Smrg #else
377*5971e316Smrg
create_preprocessor(CompilerInstance * Clang)378*5971e316Smrg static void create_preprocessor(CompilerInstance *Clang)
379*5971e316Smrg {
380*5971e316Smrg Clang->createPreprocessor();
381*5971e316Smrg }
382*5971e316Smrg
383*5971e316Smrg #endif
384*5971e316Smrg
385*5971e316Smrg #ifdef ADDPATH_TAKES_4_ARGUMENTS
386*5971e316Smrg
387*5971e316Smrg /* Add "Path" to the header search options.
388*5971e316Smrg *
389*5971e316Smrg * Do not take into account sysroot, i.e., set ignoreSysRoot to true.
390*5971e316Smrg */
add_path(HeaderSearchOptions & HSO,string Path)391*5971e316Smrg void add_path(HeaderSearchOptions &HSO, string Path)
392*5971e316Smrg {
393*5971e316Smrg HSO.AddPath(Path, frontend::Angled, false, true);
394*5971e316Smrg }
395*5971e316Smrg
396*5971e316Smrg #else
397*5971e316Smrg
398*5971e316Smrg /* Add "Path" to the header search options.
399*5971e316Smrg *
400*5971e316Smrg * Do not take into account sysroot, i.e., set IsSysRootRelative to false.
401*5971e316Smrg */
add_path(HeaderSearchOptions & HSO,string Path)402*5971e316Smrg void add_path(HeaderSearchOptions &HSO, string Path)
403*5971e316Smrg {
404*5971e316Smrg HSO.AddPath(Path, frontend::Angled, true, false, false);
405*5971e316Smrg }
406*5971e316Smrg
407*5971e316Smrg #endif
408*5971e316Smrg
409*5971e316Smrg #ifdef HAVE_SETMAINFILEID
410*5971e316Smrg
create_main_file_id(SourceManager & SM,const FileEntry * file)411*5971e316Smrg static void create_main_file_id(SourceManager &SM, const FileEntry *file)
412*5971e316Smrg {
413*5971e316Smrg SM.setMainFileID(SM.createFileID(file, SourceLocation(),
414*5971e316Smrg SrcMgr::C_User));
415*5971e316Smrg }
416*5971e316Smrg
417*5971e316Smrg #else
418*5971e316Smrg
create_main_file_id(SourceManager & SM,const FileEntry * file)419*5971e316Smrg static void create_main_file_id(SourceManager &SM, const FileEntry *file)
420*5971e316Smrg {
421*5971e316Smrg SM.createMainFileID(file);
422*5971e316Smrg }
423*5971e316Smrg
424*5971e316Smrg #endif
425*5971e316Smrg
426*5971e316Smrg #ifdef SETLANGDEFAULTS_TAKES_5_ARGUMENTS
427*5971e316Smrg
428*5971e316Smrg #include "set_lang_defaults_arg4.h"
429*5971e316Smrg
set_lang_defaults(CompilerInstance * Clang)430*5971e316Smrg static void set_lang_defaults(CompilerInstance *Clang)
431*5971e316Smrg {
432*5971e316Smrg PreprocessorOptions &PO = Clang->getPreprocessorOpts();
433*5971e316Smrg TargetOptions &TO = Clang->getTargetOpts();
434*5971e316Smrg llvm::Triple T(TO.Triple);
435*5971e316Smrg SETLANGDEFAULTS::setLangDefaults(Clang->getLangOpts(), IK_C, T,
436*5971e316Smrg setLangDefaultsArg4(PO),
437*5971e316Smrg LangStandard::lang_unspecified);
438*5971e316Smrg }
439*5971e316Smrg
440*5971e316Smrg #else
441*5971e316Smrg
set_lang_defaults(CompilerInstance * Clang)442*5971e316Smrg static void set_lang_defaults(CompilerInstance *Clang)
443*5971e316Smrg {
444*5971e316Smrg CompilerInvocation::setLangDefaults(Clang->getLangOpts(), IK_C,
445*5971e316Smrg LangStandard::lang_unspecified);
446*5971e316Smrg }
447*5971e316Smrg
448*5971e316Smrg #endif
449*5971e316Smrg
450*5971e316Smrg #ifdef SETINVOCATION_TAKES_SHARED_PTR
451*5971e316Smrg
set_invocation(CompilerInstance * Clang,CompilerInvocation * invocation)452*5971e316Smrg static void set_invocation(CompilerInstance *Clang,
453*5971e316Smrg CompilerInvocation *invocation)
454*5971e316Smrg {
455*5971e316Smrg Clang->setInvocation(std::make_shared<CompilerInvocation>(*invocation));
456*5971e316Smrg }
457*5971e316Smrg
458*5971e316Smrg #else
459*5971e316Smrg
set_invocation(CompilerInstance * Clang,CompilerInvocation * invocation)460*5971e316Smrg static void set_invocation(CompilerInstance *Clang,
461*5971e316Smrg CompilerInvocation *invocation)
462*5971e316Smrg {
463*5971e316Smrg Clang->setInvocation(invocation);
464*5971e316Smrg }
465*5971e316Smrg
466*5971e316Smrg #endif
467*5971e316Smrg
468*5971e316Smrg /* Helper function for ignore_error that only gets enabled if T
469*5971e316Smrg * (which is either const FileEntry * or llvm::ErrorOr<const FileEntry *>)
470*5971e316Smrg * has getError method, i.e., if it is llvm::ErrorOr<const FileEntry *>.
471*5971e316Smrg */
472*5971e316Smrg template <class T>
ignore_error_helper(const T obj,int,int[1][sizeof (obj.getError ())])473*5971e316Smrg static const FileEntry *ignore_error_helper(const T obj, int,
474*5971e316Smrg int[1][sizeof(obj.getError())])
475*5971e316Smrg {
476*5971e316Smrg return *obj;
477*5971e316Smrg }
478*5971e316Smrg
479*5971e316Smrg /* Helper function for ignore_error that is always enabled,
480*5971e316Smrg * but that only gets selected if the variant above is not enabled,
481*5971e316Smrg * i.e., if T is const FileEntry *.
482*5971e316Smrg */
483*5971e316Smrg template <class T>
ignore_error_helper(const T obj,long,void *)484*5971e316Smrg static const FileEntry *ignore_error_helper(const T obj, long, void *)
485*5971e316Smrg {
486*5971e316Smrg return obj;
487*5971e316Smrg }
488*5971e316Smrg
489*5971e316Smrg /* Given either a const FileEntry * or a llvm::ErrorOr<const FileEntry *>,
490*5971e316Smrg * extract out the const FileEntry *.
491*5971e316Smrg */
492*5971e316Smrg template <class T>
ignore_error(const T obj)493*5971e316Smrg static const FileEntry *ignore_error(const T obj)
494*5971e316Smrg {
495*5971e316Smrg return ignore_error_helper(obj, 0, NULL);
496*5971e316Smrg }
497*5971e316Smrg
498*5971e316Smrg /* Return the FileEntry corresponding to the given file name
499*5971e316Smrg * in the given compiler instances, ignoring any error.
500*5971e316Smrg */
getFile(CompilerInstance * Clang,std::string Filename)501*5971e316Smrg static const FileEntry *getFile(CompilerInstance *Clang, std::string Filename)
502*5971e316Smrg {
503*5971e316Smrg return ignore_error(Clang->getFileManager().getFile(Filename));
504*5971e316Smrg }
505*5971e316Smrg
506*5971e316Smrg /* Create an interface generator for the selected language and
507*5971e316Smrg * then use it to generate the interface.
508*5971e316Smrg */
generate(MyASTConsumer & consumer,SourceManager & SM)509*5971e316Smrg static void generate(MyASTConsumer &consumer, SourceManager &SM)
510*5971e316Smrg {
511*5971e316Smrg generator *gen;
512*5971e316Smrg
513*5971e316Smrg if (OutputLanguage.compare("python") == 0) {
514*5971e316Smrg gen = new python_generator(SM, consumer.exported_types,
515*5971e316Smrg consumer.exported_functions, consumer.functions);
516*5971e316Smrg } else if (OutputLanguage.compare("cpp") == 0) {
517*5971e316Smrg gen = new plain_cpp_generator(SM, consumer.exported_types,
518*5971e316Smrg consumer.exported_functions, consumer.functions);
519*5971e316Smrg } else if (OutputLanguage.compare("cpp-checked") == 0) {
520*5971e316Smrg gen = new plain_cpp_generator(SM, consumer.exported_types,
521*5971e316Smrg consumer.exported_functions, consumer.functions, true);
522*5971e316Smrg } else if (OutputLanguage.compare("cpp-checked-conversion") == 0) {
523*5971e316Smrg gen = new cpp_conversion_generator(SM, consumer.exported_types,
524*5971e316Smrg consumer.exported_functions, consumer.functions);
525*5971e316Smrg } else if (OutputLanguage.compare("template-cpp") == 0) {
526*5971e316Smrg gen = new template_cpp_generator(SM, consumer.exported_types,
527*5971e316Smrg consumer.exported_functions, consumer.functions);
528*5971e316Smrg } else {
529*5971e316Smrg cerr << "Language '" << OutputLanguage
530*5971e316Smrg << "' not recognized." << endl
531*5971e316Smrg << "Not generating bindings." << endl;
532*5971e316Smrg exit(EXIT_FAILURE);
533*5971e316Smrg }
534*5971e316Smrg
535*5971e316Smrg gen->generate();
536*5971e316Smrg }
537*5971e316Smrg
main(int argc,char * argv[])538*5971e316Smrg int main(int argc, char *argv[])
539*5971e316Smrg {
540*5971e316Smrg llvm::cl::ParseCommandLineOptions(argc, argv);
541*5971e316Smrg
542*5971e316Smrg CompilerInstance *Clang = new CompilerInstance();
543*5971e316Smrg create_diagnostics(Clang);
544*5971e316Smrg DiagnosticsEngine &Diags = Clang->getDiagnostics();
545*5971e316Smrg Diags.setSuppressSystemWarnings(true);
546*5971e316Smrg TargetInfo *target = create_target_info(Clang, Diags);
547*5971e316Smrg Clang->setTarget(target);
548*5971e316Smrg set_lang_defaults(Clang);
549*5971e316Smrg CompilerInvocation *invocation =
550*5971e316Smrg construct_invocation(InputFilename.c_str(), Diags);
551*5971e316Smrg if (invocation)
552*5971e316Smrg set_invocation(Clang, invocation);
553*5971e316Smrg Clang->createFileManager();
554*5971e316Smrg Clang->createSourceManager(Clang->getFileManager());
555*5971e316Smrg HeaderSearchOptions &HSO = Clang->getHeaderSearchOpts();
556*5971e316Smrg LangOptions &LO = Clang->getLangOpts();
557*5971e316Smrg PreprocessorOptions &PO = Clang->getPreprocessorOpts();
558*5971e316Smrg HSO.ResourceDir = ResourceDir;
559*5971e316Smrg
560*5971e316Smrg for (llvm::cl::list<string>::size_type i = 0; i < Includes.size(); ++i)
561*5971e316Smrg add_path(HSO, Includes[i]);
562*5971e316Smrg
563*5971e316Smrg PO.addMacroDef("__isl_give=__attribute__((annotate(\"isl_give\")))");
564*5971e316Smrg PO.addMacroDef("__isl_keep=__attribute__((annotate(\"isl_keep\")))");
565*5971e316Smrg PO.addMacroDef("__isl_take=__attribute__((annotate(\"isl_take\")))");
566*5971e316Smrg PO.addMacroDef("__isl_export=__attribute__((annotate(\"isl_export\")))");
567*5971e316Smrg PO.addMacroDef("__isl_overload="
568*5971e316Smrg "__attribute__((annotate(\"isl_overload\"))) "
569*5971e316Smrg "__attribute__((annotate(\"isl_export\")))");
570*5971e316Smrg PO.addMacroDef("__isl_constructor=__attribute__((annotate(\"isl_constructor\"))) __attribute__((annotate(\"isl_export\")))");
571*5971e316Smrg PO.addMacroDef("__isl_subclass(super)=__attribute__((annotate(\"isl_subclass(\" #super \")\"))) __attribute__((annotate(\"isl_export\")))");
572*5971e316Smrg
573*5971e316Smrg create_preprocessor(Clang);
574*5971e316Smrg Preprocessor &PP = Clang->getPreprocessor();
575*5971e316Smrg
576*5971e316Smrg PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(), LO);
577*5971e316Smrg
578*5971e316Smrg const FileEntry *file = getFile(Clang, InputFilename);
579*5971e316Smrg assert(file);
580*5971e316Smrg create_main_file_id(Clang->getSourceManager(), file);
581*5971e316Smrg
582*5971e316Smrg Clang->createASTContext();
583*5971e316Smrg MyASTConsumer consumer;
584*5971e316Smrg Sema *sema = new Sema(PP, Clang->getASTContext(), consumer);
585*5971e316Smrg
586*5971e316Smrg Diags.getClient()->BeginSourceFile(LO, &PP);
587*5971e316Smrg ParseAST(*sema);
588*5971e316Smrg Diags.getClient()->EndSourceFile();
589*5971e316Smrg
590*5971e316Smrg generate(consumer, Clang->getSourceManager());
591*5971e316Smrg
592*5971e316Smrg delete sema;
593*5971e316Smrg delete Clang;
594*5971e316Smrg llvm::llvm_shutdown();
595*5971e316Smrg
596*5971e316Smrg if (Diags.hasErrorOccurred())
597*5971e316Smrg return EXIT_FAILURE;
598*5971e316Smrg return EXIT_SUCCESS;
599*5971e316Smrg }
600