34#include "isl_config.h"
41#ifdef HAVE_ADT_OWNINGPTR_H
42#include <llvm/ADT/OwningPtr.h>
46#ifdef HAVE_LLVM_OPTION_ARG_H
47#include <llvm/Option/Arg.h>
49#include <llvm/Support/raw_ostream.h>
50#include <llvm/Support/CommandLine.h>
51#ifdef HAVE_TARGETPARSER_HOST_H
52#include <llvm/TargetParser/Host.h>
54#include <llvm/Support/Host.h>
56#include <llvm/Support/ManagedStatic.h>
57#include <clang/AST/ASTContext.h>
58#include <clang/AST/ASTConsumer.h>
59#include <clang/Basic/Builtins.h>
60#include <clang/Basic/FileSystemOptions.h>
61#include <clang/Basic/FileManager.h>
62#include <clang/Basic/TargetOptions.h>
63#include <clang/Basic/TargetInfo.h>
64#include <clang/Basic/Version.h>
65#include <clang/Driver/Compilation.h>
66#include <clang/Driver/Driver.h>
67#include <clang/Driver/Tool.h>
68#include <clang/Frontend/CompilerInstance.h>
69#include <clang/Frontend/CompilerInvocation.h>
70#ifdef HAVE_BASIC_DIAGNOSTICOPTIONS_H
71#include <clang/Basic/DiagnosticOptions.h>
73#include <clang/Frontend/DiagnosticOptions.h>
75#include <clang/Frontend/TextDiagnosticPrinter.h>
76#include <clang/Frontend/Utils.h>
77#include <clang/Lex/HeaderSearch.h>
78#ifdef HAVE_LEX_PREPROCESSOROPTIONS_H
79#include <clang/Lex/PreprocessorOptions.h>
81#include <clang/Frontend/PreprocessorOptions.h>
83#include <clang/Lex/Preprocessor.h>
84#include <clang/Parse/ParseAST.h>
85#include <clang/Sema/Sema.h>
96using namespace clang::driver;
97#ifdef HAVE_LLVM_OPTION_ARG_H
98using namespace llvm::opt;
101#ifdef HAVE_ADT_OWNINGPTR_H
102#define unique_ptr llvm::OwningPtr
106 llvm::cl::Required, llvm::cl::desc(
"<input file>"));
108 llvm::cl::desc(
"Header search path"),
109 llvm::cl::value_desc(
"path"), llvm::cl::Prefix);
112 llvm::cl::ValueRequired,
"language",
113 llvm::cl::desc(
"Bindings to generate"),
114 llvm::cl::value_desc(
"name"));
117 CLANG_PREFIX
"/lib/clang/" CLANG_VERSION_STRING;
125 if (!decl->hasAttrs())
128 AttrVec attrs = decl->getAttrs();
129 for (AttrVec::const_iterator i = attrs.begin() ; i != attrs.end(); ++i) {
130 const AnnotateAttr *ann = dyn_cast<AnnotateAttr>(*i);
133 if (ann->getAnnotation().str() ==
name)
161 if (!D.isSingleDecl())
162 return HandleTopLevelDeclContinue;
163 decl = D.getSingleDecl();
164 if (isa<FunctionDecl>(decl))
165 functions.insert(cast<FunctionDecl>(decl));
167 return HandleTopLevelDeclContinue;
168 switch (decl->getKind()) {
178 return HandleTopLevelDeclContinue;
184#ifdef HAVE_CXXISPRODUCTION
185static Driver *construct_driver(
const char *
binary, DiagnosticsEngine &Diags)
187 return new Driver(
binary, llvm::sys::getDefaultTargetTriple(),
188 "",
false,
false, Diags);
190#elif defined(HAVE_ISPRODUCTION)
191static Driver *construct_driver(
const char *
binary, DiagnosticsEngine &Diags)
193 return new Driver(
binary, llvm::sys::getDefaultTargetTriple(),
196#elif defined(DRIVER_CTOR_TAKES_DEFAULTIMAGENAME)
197static Driver *construct_driver(
const char *
binary, DiagnosticsEngine &Diags)
199 return new Driver(
binary, llvm::sys::getDefaultTargetTriple(),
203static Driver *construct_driver(
const char *
binary, DiagnosticsEngine &Diags)
205 return new Driver(
binary, llvm::sys::getDefaultTargetTriple(), Diags);
209namespace clang {
namespace driver {
class Job; } }
215 static Job *command(Job *J) {
return J; }
216 static Job *command(Job &J) {
return &J; }
217 static Command *command(Command &
C) {
return &
C; }
220#ifdef CREATE_FROM_ARGS_TAKES_ARRAYREF
225static void create_from_args(CompilerInvocation &invocation,
226 const ArgStringList *args, DiagnosticsEngine &Diags)
228 CompilerInvocation::CreateFromArgs(invocation, *args, Diags);
236static void create_from_args(CompilerInvocation &invocation,
237 const ArgStringList *args, DiagnosticsEngine &Diags)
239 CompilerInvocation::CreateFromArgs(invocation, args->data() + 1,
240 args->data() + args->size(),
251static void set_sysroot(ArgStringList &args)
253 args.push_back(
"-isysroot");
254 args.push_back(CLANG_SYSROOT);
261static void set_sysroot(ArgStringList &args)
272 DiagnosticsEngine &Diags)
274 const char *
binary = CLANG_PREFIX
"/bin/clang";
275 const unique_ptr<Driver> driver(construct_driver(
binary, Diags));
276 std::vector<const char *> Argv;
278 Argv.push_back(filename);
279 const unique_ptr<Compilation> compilation(
280 driver->BuildCompilation(llvm::ArrayRef<const char *>(Argv)));
281 JobList &Jobs = compilation->getJobs();
283 Command *cmd = cast<Command>(ClangAPI::command(*Jobs.begin()));
284 if (strcmp(cmd->getCreator().getName(),
"clang"))
287 ArgStringList args = cmd->getArguments();
290 CompilerInvocation *invocation =
new CompilerInvocation;
291 create_from_args(*invocation, &args, Diags);
298 DiagnosticsEngine &Diags)
305#ifdef HAVE_BASIC_DIAGNOSTICOPTIONS_H
309 return new TextDiagnosticPrinter(llvm::errs(),
new DiagnosticOptions());
316 DiagnosticOptions DO;
317 return new TextDiagnosticPrinter(llvm::errs(), DO);
322#ifdef CREATETARGETINFO_TAKES_SHARED_PTR
325 DiagnosticsEngine &Diags)
327 shared_ptr<TargetOptions> TO = Clang->getInvocation().TargetOpts;
328 TO->Triple = llvm::sys::getDefaultTargetTriple();
329 return TargetInfo::CreateTargetInfo(Diags, TO);
332#elif defined(CREATETARGETINFO_TAKES_POINTER)
335 DiagnosticsEngine &Diags)
337 TargetOptions &TO = Clang->getTargetOpts();
338 TO.Triple = llvm::sys::getDefaultTargetTriple();
339 return TargetInfo::CreateTargetInfo(Diags, &TO);
345 DiagnosticsEngine &Diags)
347 TargetOptions &TO = Clang->getTargetOpts();
348 TO.Triple = llvm::sys::getDefaultTargetTriple();
349 return TargetInfo::CreateTargetInfo(Diags, TO);
354#ifdef CREATEDIAGNOSTICS_TAKES_ARG
370#ifdef CREATEPREPROCESSOR_TAKES_TUKIND
374 Clang->createPreprocessor(TU_Complete);
381 Clang->createPreprocessor();
386#ifdef ADDPATH_TAKES_4_ARGUMENTS
392void add_path(HeaderSearchOptions &HSO,
string Path)
394 HSO.AddPath(Path, frontend::Angled,
false,
true);
403void add_path(HeaderSearchOptions &HSO,
string Path)
405 HSO.AddPath(Path, frontend::Angled,
true,
false,
false);
410#ifdef HAVE_SETMAINFILEID
415 SM.setMainFileID(SM.createFileID(file, SourceLocation(),
423 SM.createMainFileID(file);
428#ifdef SETLANGDEFAULTS_TAKES_5_ARGUMENTS
434 PreprocessorOptions &PO = Clang->getPreprocessorOpts();
435 TargetOptions &TO = Clang->getTargetOpts();
436 llvm::Triple T(TO.Triple);
437 SETLANGDEFAULTS::setLangDefaults(Clang->getLangOpts(), IK_C, T,
439 LangStandard::lang_unspecified);
446 CompilerInvocation::setLangDefaults(Clang->getLangOpts(), IK_C,
447 LangStandard::lang_unspecified);
452#ifdef SETINVOCATION_TAKES_SHARED_PTR
455 CompilerInvocation *invocation)
457 Clang->setInvocation(std::make_shared<CompilerInvocation>(*invocation));
463 CompilerInvocation *invocation)
465 Clang->setInvocation(invocation);
476 int[1][
sizeof(
obj.getError())])
507template <
class T,
class =
void>
511 public std::true_type {};
521 typename std::enable_if<HasGetFileRef<T>::value,
bool>
::type =
true>
523 ->
decltype(*
obj.getFileRef(filename))
525 auto file =
obj.getFileRef(filename);
530 typename std::enable_if<!HasGetFileRef<T>::value,
bool>
::type =
true>
531static const FileEntry *
getFile(T&
obj,
const std::string &filename)
554 }
else if (
OutputLanguage.compare(
"cpp-checked-conversion") == 0) {
562 <<
"' not recognized." << endl
563 <<
"Not generating bindings." << endl;
570int main(
int argc,
char *argv[])
572 llvm::cl::ParseCommandLineOptions(argc, argv);
574 CompilerInstance *Clang =
new CompilerInstance();
576 DiagnosticsEngine &Diags = Clang->getDiagnostics();
577 Diags.setSuppressSystemWarnings(
true);
579 Clang->setTarget(target);
581 CompilerInvocation *invocation =
585 Clang->createFileManager();
586 Clang->createSourceManager(Clang->getFileManager());
587 HeaderSearchOptions &HSO = Clang->getHeaderSearchOpts();
588 LangOptions &LO = Clang->getLangOpts();
589 PreprocessorOptions &PO = Clang->getPreprocessorOpts();
592 for (llvm::cl::list<string>::size_type i = 0; i <
Includes.size(); ++i)
595 PO.addMacroDef(
"__isl_give=__attribute__((annotate(\"isl_give\")))");
596 PO.addMacroDef(
"__isl_keep=__attribute__((annotate(\"isl_keep\")))");
597 PO.addMacroDef(
"__isl_take=__attribute__((annotate(\"isl_take\")))");
598 PO.addMacroDef(
"__isl_export=__attribute__((annotate(\"isl_export\")))");
599 PO.addMacroDef(
"__isl_overload="
600 "__attribute__((annotate(\"isl_overload\"))) "
601 "__attribute__((annotate(\"isl_export\")))");
602 PO.addMacroDef(
"__isl_constructor=__attribute__((annotate(\"isl_constructor\"))) __attribute__((annotate(\"isl_export\")))");
603 PO.addMacroDef(
"__isl_subclass(super)=__attribute__((annotate(\"isl_subclass(\" #super \")\"))) __attribute__((annotate(\"isl_export\")))");
606 Preprocessor &PP = Clang->getPreprocessor();
608 PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(), LO);
613 Clang->createASTContext();
615 Sema *sema =
new Sema(PP, Clang->getASTContext(), consumer);
617 Diags.getClient()->BeginSourceFile(LO, &PP);
619 Diags.getClient()->EndSourceFile();
621 generate(consumer, Clang->getSourceManager());
625 llvm::llvm_shutdown();
627 if (Diags.hasErrorOccurred())
virtual void generate()=0
set< FunctionDecl * > functions
set< RecordDecl * > exported_types
set< FunctionDecl * > exported_functions
virtual HandleTopLevelDeclReturn HandleTopLevelDecl(DeclGroupRef D)