clang API Documentation

CreateInvocationFromCommandLine.cpp
Go to the documentation of this file.
00001 //===--- CreateInvocationFromCommandLine.cpp - CompilerInvocation from Args ==//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // Construct a compiler invocation object for command line driver arguments
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "clang/Frontend/Utils.h"
00015 #include "clang/Basic/DiagnosticOptions.h"
00016 #include "clang/Driver/Compilation.h"
00017 #include "clang/Driver/Driver.h"
00018 #include "clang/Driver/Options.h"
00019 #include "clang/Driver/Tool.h"
00020 #include "clang/Frontend/CompilerInstance.h"
00021 #include "clang/Frontend/FrontendDiagnostic.h"
00022 #include "llvm/Option/ArgList.h"
00023 #include "llvm/Support/Host.h"
00024 using namespace clang;
00025 using namespace llvm::opt;
00026 
00027 /// createInvocationFromCommandLine - Construct a compiler invocation object for
00028 /// a command line argument vector.
00029 ///
00030 /// \return A CompilerInvocation, or 0 if none was built for the given
00031 /// argument vector.
00032 CompilerInvocation *
00033 clang::createInvocationFromCommandLine(ArrayRef<const char *> ArgList,
00034                             IntrusiveRefCntPtr<DiagnosticsEngine> Diags) {
00035   if (!Diags.get()) {
00036     // No diagnostics engine was provided, so create our own diagnostics object
00037     // with the default options.
00038     Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions);
00039   }
00040 
00041   SmallVector<const char *, 16> Args;
00042   Args.push_back("<clang>"); // FIXME: Remove dummy argument.
00043   Args.insert(Args.end(), ArgList.begin(), ArgList.end());
00044 
00045   // FIXME: Find a cleaner way to force the driver into restricted modes.
00046   Args.push_back("-fsyntax-only");
00047 
00048   // FIXME: We shouldn't have to pass in the path info.
00049   driver::Driver TheDriver("clang", llvm::sys::getDefaultTargetTriple(),
00050                            *Diags);
00051 
00052   // Don't check that inputs exist, they may have been remapped.
00053   TheDriver.setCheckInputsExist(false);
00054 
00055   std::unique_ptr<driver::Compilation> C(TheDriver.BuildCompilation(Args));
00056 
00057   // Just print the cc1 options if -### was present.
00058   if (C->getArgs().hasArg(driver::options::OPT__HASH_HASH_HASH)) {
00059     C->getJobs().Print(llvm::errs(), "\n", true);
00060     return nullptr;
00061   }
00062 
00063   // We expect to get back exactly one command job, if we didn't something
00064   // failed.
00065   const driver::JobList &Jobs = C->getJobs();
00066   if (Jobs.size() != 1 || !isa<driver::Command>(*Jobs.begin())) {
00067     SmallString<256> Msg;
00068     llvm::raw_svector_ostream OS(Msg);
00069     Jobs.Print(OS, "; ", true);
00070     Diags->Report(diag::err_fe_expected_compiler_job) << OS.str();
00071     return nullptr;
00072   }
00073 
00074   const driver::Command &Cmd = cast<driver::Command>(*Jobs.begin());
00075   if (StringRef(Cmd.getCreator().getName()) != "clang") {
00076     Diags->Report(diag::err_fe_expected_clang_command);
00077     return nullptr;
00078   }
00079 
00080   const ArgStringList &CCArgs = Cmd.getArguments();
00081   std::unique_ptr<CompilerInvocation> CI(new CompilerInvocation());
00082   if (!CompilerInvocation::CreateFromArgs(*CI,
00083                                      const_cast<const char **>(CCArgs.data()),
00084                                      const_cast<const char **>(CCArgs.data()) +
00085                                      CCArgs.size(),
00086                                      *Diags))
00087     return nullptr;
00088   return CI.release();
00089 }