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