diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/CIndex/CIndex.cpp | 190 | ||||
| -rw-r--r-- | tools/CIndex/CIndex.exports | 3 | ||||
| -rw-r--r-- | tools/CIndex/CMakeLists.txt | 15 | ||||
| -rw-r--r-- | tools/CIndex/Makefile | 5 | ||||
| -rw-r--r-- | tools/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | tools/Makefile | 2 | ||||
| -rw-r--r-- | tools/c-index-test/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | tools/c-index-test/Makefile | 6 | ||||
| -rw-r--r-- | tools/c-index-test/c-index-test.c | 101 | ||||
| -rw-r--r-- | tools/clang-cc/CMakeLists.txt | 32 | ||||
| -rw-r--r-- | tools/clang-cc/Makefile | 32 | ||||
| -rw-r--r-- | tools/clang-cc/Options.cpp | 1265 | ||||
| -rw-r--r-- | tools/clang-cc/Options.h | 54 | ||||
| -rw-r--r-- | tools/clang-cc/clang-cc.cpp | 408 | ||||
| -rw-r--r-- | tools/driver/CMakeLists.txt | 19 | ||||
| -rw-r--r-- | tools/driver/Makefile | 21 | ||||
| -rw-r--r-- | tools/driver/cc1_main.cpp | 319 | ||||
| -rw-r--r-- | tools/driver/driver.cpp | 21 | ||||
| -rw-r--r-- | tools/index-test/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | tools/index-test/Makefile | 6 | ||||
| -rw-r--r-- | tools/index-test/index-test.cpp | 46 | ||||
| -rwxr-xr-x | tools/scan-build/ccc-analyzer | 77 | ||||
| -rwxr-xr-x | tools/scan-build/scan-build | 132 | 
23 files changed, 771 insertions, 1991 deletions
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp index 4681b939cea2..fe3aa3769414 100644 --- a/tools/CIndex/CIndex.cpp +++ b/tools/CIndex/CIndex.cpp @@ -12,24 +12,26 @@  //===----------------------------------------------------------------------===//  #include "clang-c/Index.h" -#include "clang/Index/Program.h" -#include "clang/Index/Indexer.h" -#include "clang/Index/ASTLocation.h" -#include "clang/Index/Utils.h" -#include "clang/Sema/CodeCompleteConsumer.h" +#include "clang/AST/Decl.h"  #include "clang/AST/DeclVisitor.h"  #include "clang/AST/StmtVisitor.h" -#include "clang/AST/Decl.h"  #include "clang/Basic/FileManager.h"  #include "clang/Basic/SourceManager.h" +#include "clang/Basic/Version.h"  #include "clang/Frontend/ASTUnit.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Index/ASTLocation.h" +#include "clang/Index/Indexer.h" +#include "clang/Index/Program.h" +#include "clang/Index/Utils.h" +#include "clang/Sema/CodeCompleteConsumer.h"  #include "llvm/ADT/StringExtras.h"  #include "llvm/Config/config.h"  #include "llvm/Support/Compiler.h"  #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h"  #include "llvm/System/Path.h"  #include "llvm/System/Program.h" -#include "llvm/Support/raw_ostream.h"  #include <cstdio>  #include <vector> @@ -291,10 +293,25 @@ public:  };  class CIndexer : public Indexer { +  DiagnosticOptions DiagOpts; +  IgnoreDiagnosticsClient IgnoreDiagClient; +  llvm::OwningPtr<Diagnostic> TextDiags; +  Diagnostic IgnoreDiags; +  bool UseExternalASTGeneration; +  bool OnlyLocalDecls; +  bool DisplayDiagnostics; + +  llvm::sys::Path ClangPath; +  public:    explicit CIndexer(Program *prog) : Indexer(*prog), +                                     IgnoreDiags(&IgnoreDiagClient), +                                     UseExternalASTGeneration(false),                                       OnlyLocalDecls(false), -                                     DisplayDiagnostics(false) {} +                                     DisplayDiagnostics(false) { +    TextDiags.reset( +      CompilerInstance::createDiagnostics(DiagOpts, 0, 0)); +  }    virtual ~CIndexer() { delete &getProgram(); } @@ -304,18 +321,25 @@ public:    bool getOnlyLocalDecls() const { return OnlyLocalDecls; }    void setOnlyLocalDecls(bool Local = true) { OnlyLocalDecls = Local; } +  bool getDisplayDiagnostics() const { return DisplayDiagnostics; }    void setDisplayDiagnostics(bool Display = true) {      DisplayDiagnostics = Display;    } -  bool getDisplayDiagnostics() const { return DisplayDiagnostics; } + +  bool getUseExternalASTGeneration() const { return UseExternalASTGeneration; } +  void setUseExternalASTGeneration(bool Value) { +    UseExternalASTGeneration = Value; +  } + +  Diagnostic &getDiags() { +    return DisplayDiagnostics ? *TextDiags : IgnoreDiags; +  }    /// \brief Get the path of the clang binary.    const llvm::sys::Path& getClangPath(); -private: -  bool OnlyLocalDecls; -  bool DisplayDiagnostics; -  llvm::sys::Path ClangPath; +  /// \brief Get the path of the clang resource files. +  std::string getClangResourcesPath();  };  const llvm::sys::Path& CIndexer::getClangPath() { @@ -357,6 +381,22 @@ const llvm::sys::Path& CIndexer::getClangPath() {    return ClangPath;  } +std::string CIndexer::getClangResourcesPath() { +  llvm::sys::Path P = getClangPath(); + +  if (!P.empty()) { +    P.eraseComponent();  // Remove /clang from foo/bin/clang +    P.eraseComponent();  // Remove /bin   from foo/bin + +    // Get foo/lib/clang/<version>/include +    P.appendComponent("lib"); +    P.appendComponent("clang"); +    P.appendComponent(CLANG_VERSION_STRING); +  } + +  return P.str(); +} +  }  static SourceLocation getLocationFromCursor(CXCursor C, @@ -452,25 +492,21 @@ void clang_disposeIndex(CXIndex CIdx) {    delete static_cast<CIndexer *>(CIdx);  } +void clang_setUseExternalASTGeneration(CXIndex CIdx, int value) { +  assert(CIdx && "Passed null CXIndex"); +  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); +  CXXIdx->setUseExternalASTGeneration(value); +} +  // FIXME: need to pass back error info.  CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,                                                const char *ast_filename) {    assert(CIdx && "Passed null CXIndex");    CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); -  std::string astName(ast_filename); -  std::string ErrMsg; - -  CXTranslationUnit TU = -    ASTUnit::LoadFromPCHFile(astName, &ErrMsg, -                             CXXIdx->getDisplayDiagnostics() ? -                             NULL : new IgnoreDiagnosticsClient(), -                             CXXIdx->getOnlyLocalDecls(), -                             /* UseBumpAllocator = */ true); -  if (CXXIdx->getDisplayDiagnostics() && !ErrMsg.empty()) -    llvm::errs() << "clang_createTranslationUnit: " << ErrMsg  << '\n'; - -  return TU; +  return ASTUnit::LoadFromPCHFile(ast_filename, CXXIdx->getDiags(), +                                  CXXIdx->getOnlyLocalDecls(), +                                  /* UseBumpAllocator = */ true);  }  CXTranslationUnit @@ -481,6 +517,33 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx,    assert(CIdx && "Passed null CXIndex");    CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); +  if (!CXXIdx->getUseExternalASTGeneration()) { +    llvm::SmallVector<const char *, 16> Args; + +    // The 'source_filename' argument is optional.  If the caller does not +    // specify it then it is assumed that the source file is specified +    // in the actual argument list. +    if (source_filename) +      Args.push_back(source_filename); +    Args.insert(Args.end(), command_line_args, +                command_line_args + num_command_line_args); + +    unsigned NumErrors = CXXIdx->getDiags().getNumErrors(); +    llvm::OwningPtr<ASTUnit> Unit( +      ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(), +                                   CXXIdx->getDiags(), +                                   CXXIdx->getClangResourcesPath(), +                                   CXXIdx->getOnlyLocalDecls(), +                                   /* UseBumpAllocator = */ true)); + +    // FIXME: Until we have broader testing, just drop the entire AST if we +    // encountered an error. +    if (NumErrors != CXXIdx->getDiags().getNumErrors()) +      return 0; + +    return Unit.take(); +  } +    // Build up the arguments for invoking 'clang'.    std::vector<const char *> argv; @@ -568,9 +631,29 @@ void clang_loadTranslationUnit(CXTranslationUnit CTUnit,    ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);    ASTContext &Ctx = CXXUnit->getASTContext(); -  TUVisitor DVisit(CTUnit, callback, CData, -                   CXXUnit->getOnlyLocalDecls()? 1 : Decl::MaxPCHLevel); -  DVisit.Visit(Ctx.getTranslationUnitDecl()); +  unsigned PCHLevel = Decl::MaxPCHLevel; + +  // Set the PCHLevel to filter out unwanted decls if requested. +  if (CXXUnit->getOnlyLocalDecls()) { +    PCHLevel = 0; + +    // If the main input was an AST, bump the level. +    if (CXXUnit->isMainFileAST()) +      ++PCHLevel; +  } + +  TUVisitor DVisit(CTUnit, callback, CData, PCHLevel); + +  // If using a non-AST based ASTUnit, iterate over the stored list of top-level +  // decls. +  if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls()) { +    const std::vector<Decl*> &TLDs = CXXUnit->getTopLevelDecls(); +    for (std::vector<Decl*>::const_iterator it = TLDs.begin(), +           ie = TLDs.end(); it != ie; ++it) { +      DVisit.Visit(*it); +    } +  } else +    DVisit.Visit(Ctx.getTranslationUnitDecl());  }  void clang_loadDeclaration(CXDecl Dcl, @@ -1082,7 +1165,7 @@ const char *clang_getCompletionChunkText(CXCompletionString completion_string,    case CodeCompletionString::CK_Optional:      // Note: treated as an empty text block. -    return 0; +    return "";    }    // Should be unreachable, but let's be careful. @@ -1141,6 +1224,8 @@ void clang_codeComplete(CXIndex CIdx,                          const char *source_filename,                          int num_command_line_args,                          const char **command_line_args, +                        unsigned num_unsaved_files, +                        struct CXUnsavedFile *unsaved_files,                          const char *complete_filename,                          unsigned complete_line,                          unsigned complete_column, @@ -1149,6 +1234,9 @@ void clang_codeComplete(CXIndex CIdx,    // The indexer, which is mainly used to determine where diagnostics go.    CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); +  // The set of temporary files that we've built. +  std::vector<llvm::sys::Path> TemporaryFiles; +    // Build up the arguments for invoking 'clang'.    std::vector<const char *> argv; @@ -1163,17 +1251,53 @@ void clang_codeComplete(CXIndex CIdx,    // Add the appropriate '-code-completion-at=file:line:column' argument    // to perform code completion, with an "-Xclang" preceding it.    std::string code_complete_at; -  code_complete_at += "-code-completion-at=";    code_complete_at += complete_filename;    code_complete_at += ":";    code_complete_at += llvm::utostr(complete_line);    code_complete_at += ":";    code_complete_at += llvm::utostr(complete_column);    argv.push_back("-Xclang"); +  argv.push_back("-code-completion-at"); +  argv.push_back("-Xclang");    argv.push_back(code_complete_at.c_str());    argv.push_back("-Xclang");    argv.push_back("-no-code-completion-debug-printer"); +  std::vector<std::string> RemapArgs; +  for (unsigned i = 0; i != num_unsaved_files; ++i) { +    char tmpFile[L_tmpnam]; +    char *tmpFileName = tmpnam(tmpFile); + +    // Write the contents of this unsaved file into the temporary file. +    llvm::sys::Path SavedFile(tmpFileName); +    std::string ErrorInfo; +    llvm::raw_fd_ostream OS(SavedFile.c_str(), ErrorInfo); +    if (!ErrorInfo.empty()) +      continue; +     +    OS.write(unsaved_files[i].Contents, unsaved_files[i].Length); +    OS.close(); +    if (OS.has_error()) { +      SavedFile.eraseFromDisk(); +      continue; +    } + +    // Remap the file. +    std::string RemapArg = unsaved_files[i].Filename; +    RemapArg += ';'; +    RemapArg += tmpFileName; +    RemapArgs.push_back("-Xclang"); +    RemapArgs.push_back("-remap-file"); +    RemapArgs.push_back("-Xclang"); +    RemapArgs.push_back(RemapArg); +    TemporaryFiles.push_back(SavedFile); +  } + +  // The pointers into the elements of RemapArgs are stable because we +  // won't be adding anything to RemapArgs after this point. +  for (unsigned i = 0, e = RemapArgs.size(); i != e; ++i) +    argv.push_back(RemapArgs[i].c_str()); +    // Add the source file name (FIXME: later, we'll want to build temporary    // file from the buffer, or just feed the source text via standard input).    if (source_filename) @@ -1203,6 +1327,7 @@ void clang_codeComplete(CXIndex CIdx,    char tmpFile[L_tmpnam];    char *tmpFileName = tmpnam(tmpFile);    llvm::sys::Path ResultsFile(tmpFileName); +  TemporaryFiles.push_back(ResultsFile);    // Invoke 'clang'.    llvm::sys::Path DevNull; // leave empty, causes redirection to /dev/null @@ -1255,7 +1380,8 @@ void clang_codeComplete(CXIndex CIdx,      delete F;    } -  ResultsFile.eraseFromDisk(); +  for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i) +    TemporaryFiles[i].eraseFromDisk();  }  } // end extern "C" diff --git a/tools/CIndex/CIndex.exports b/tools/CIndex/CIndex.exports index 2892ce50e70d..458ad1028359 100644 --- a/tools/CIndex/CIndex.exports +++ b/tools/CIndex/CIndex.exports @@ -6,6 +6,7 @@ _clang_disposeIndex  _clang_disposeString  _clang_disposeTranslationUnit  _clang_equalCursors +_clang_getCString  _clang_getCompletionChunkCompletionString  _clang_getCompletionChunkKind  _clang_getCompletionChunkText @@ -19,7 +20,6 @@ _clang_getCursorLine  _clang_getCursorSource  _clang_getCursorSourceFile  _clang_getCursorSpelling -_clang_getCString  _clang_getDeclColumn  _clang_getDeclLine  _clang_getDeclSource @@ -41,3 +41,4 @@ _clang_isInvalid  _clang_isReference  _clang_loadDeclaration  _clang_loadTranslationUnit +_clang_setUseExternalASTGeneration diff --git a/tools/CIndex/CMakeLists.txt b/tools/CIndex/CMakeLists.txt index 69de8a1acffb..a3ff3db2d9b5 100644 --- a/tools/CIndex/CMakeLists.txt +++ b/tools/CIndex/CMakeLists.txt @@ -3,11 +3,20 @@ set(SHARED_LIBRARY TRUE)  set(LLVM_NO_RTTI 1)  set(LLVM_USED_LIBS -  clangFrontend clangIndex clangSema clangAnalysis clangAST clangParse clangLex clangBasic) +  clangIndex +  clangFrontend +  clangDriver +  clangSema +  clangAnalysis +  clangAST +  clangParse +  clangLex +  clangBasic)  set( LLVM_LINK_COMPONENTS -  MC -  support +  bitreader +  mc +  core    )  add_clang_library(CIndex CIndex.cpp) diff --git a/tools/CIndex/Makefile b/tools/CIndex/Makefile index a34f68ba115b..94f04670000d 100644 --- a/tools/CIndex/Makefile +++ b/tools/CIndex/Makefile @@ -21,8 +21,9 @@ include $(LEVEL)/Makefile.config  LINK_LIBS_IN_SHARED = 1  SHARED_LIBRARY = 1 -LINK_COMPONENTS := MC support -USEDLIBS = clangFrontend.a clangIndex.a clangSema.a clangAnalysis.a clangAST.a clangParse.a clangLex.a clangBasic.a +LINK_COMPONENTS := bitreader mc core +USEDLIBS = clangIndex.a clangFrontend.a clangDriver.a clangSema.a \ +	   clangAnalysis.a clangAST.a clangParse.a clangLex.a clangBasic.a  include $(LEVEL)/Makefile.common diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 8c666dd71a0c..46e4ae946f19 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,5 +1,4 @@  add_subdirectory(CIndex)  add_subdirectory(c-index-test) -add_subdirectory(clang-cc)  add_subdirectory(driver)  add_subdirectory(index-test) diff --git a/tools/Makefile b/tools/Makefile index 0e98439c3821..a30932b8996f 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -8,6 +8,6 @@  ##===----------------------------------------------------------------------===##  LEVEL := ../../.. -DIRS := clang-cc driver index-test CIndex c-index-test +DIRS := driver index-test CIndex c-index-test  include $(LEVEL)/Makefile.common diff --git a/tools/c-index-test/CMakeLists.txt b/tools/c-index-test/CMakeLists.txt index 4678461de1f4..f0a34a57987e 100644 --- a/tools/c-index-test/CMakeLists.txt +++ b/tools/c-index-test/CMakeLists.txt @@ -5,8 +5,8 @@ set( LLVM_USED_LIBS    clangIndex    clangFrontend    clangDriver -  clangAnalysis    clangSema +  clangAnalysis    clangAST    clangParse    clangLex @@ -16,6 +16,7 @@ set( LLVM_USED_LIBS  set( LLVM_LINK_COMPONENTS    bitreader    mc +  core    )  add_clang_executable(c-index-test diff --git a/tools/c-index-test/Makefile b/tools/c-index-test/Makefile index ae49bf4d7af9..06e24053aa0a 100644 --- a/tools/c-index-test/Makefile +++ b/tools/c-index-test/Makefile @@ -18,8 +18,8 @@ TOOL_NO_EXPORTS = 1  include $(LEVEL)/Makefile.config -LINK_COMPONENTS := bitreader mc -USEDLIBS = CIndex.a clangIndex.a clangFrontend.a clangDriver.a clangAnalysis.a \ -	   clangSema.a clangAST.a clangParse.a clangLex.a clangBasic.a +LINK_COMPONENTS := bitreader mc core +USEDLIBS = CIndex.a clangIndex.a clangFrontend.a clangDriver.a clangSema.a \ +	   clangAnalysis.a clangAST.a clangParse.a clangLex.a clangBasic.a  include $(LLVM_SRC_ROOT)/Makefile.rules diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index 5364d7948c5d..7300585a1d88 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -179,12 +179,17 @@ int perform_test_load_tu(const char *file, const char *filter) {  }  int perform_test_load_source(int argc, const char **argv, const char *filter) { +  const char *UseExternalASTs = +    getenv("CINDEXTEST_USE_EXTERNAL_AST_GENERATION");    CXIndex Idx;    CXTranslationUnit TU;    Idx = clang_createIndex(/* excludeDeclsFromPCH */                            !strcmp(filter, "local") ? 1 : 0,                            /* displayDiagnostics */ 1); +  if (UseExternalASTs && strlen(UseExternalASTs)) +    clang_setUseExternalASTGeneration(Idx, 1); +    TU = clang_createTranslationUnitFromSourceFile(Idx, 0, argc, argv);    if (!TU) {      fprintf(stderr, "Unable to load translation unit!\n"); @@ -389,6 +394,91 @@ void print_completion_result(CXCompletionResult *completion_result,    fprintf(file, "\n");  } +void free_remapped_files(struct CXUnsavedFile *unsaved_files, +                         int num_unsaved_files) { +  int i; +  for (i = 0; i != num_unsaved_files; ++i) { +    free((char *)unsaved_files[i].Filename); +    free((char *)unsaved_files[i].Contents); +  } +} + +int parse_remapped_files(int argc, const char **argv, int start_arg, +                         struct CXUnsavedFile **unsaved_files, +                          int *num_unsaved_files) { +  int i; +  int arg; +  int prefix_len = strlen("-remap-file="); +  *unsaved_files = 0; +  *num_unsaved_files = 0; + +  /* Count the number of remapped files. */ +  for (arg = start_arg; arg < argc; ++arg) { +    if (strncmp(argv[arg], "-remap-file=", prefix_len)) +      break; + +    ++*num_unsaved_files; +  } + +  if (*num_unsaved_files == 0) +    return 0; + +  *unsaved_files +    = (struct CXUnsavedFile *)malloc(sizeof(struct CXUnsavedFile) *  +                                     *num_unsaved_files); +  for (arg = start_arg, i = 0; i != *num_unsaved_files; ++i, ++arg) { +    struct CXUnsavedFile *unsaved = *unsaved_files + i; +    const char *arg_string = argv[arg] + prefix_len; +    int filename_len; +    char *filename; +    char *contents; +    FILE *to_file; +    const char *semi = strchr(arg_string, ';'); +    if (!semi) { +      fprintf(stderr,  +              "error: -remap-file=from;to argument is missing semicolon\n"); +      free_remapped_files(*unsaved_files, i); +      *unsaved_files = 0; +      *num_unsaved_files = 0; +      return -1; +    } + +    /* Open the file that we're remapping to. */ +    to_file = fopen(semi + 1, "r"); +    if (!to_file) { +      fprintf(stderr, "error: cannot open file %s that we are remapping to\n", +              semi + 1); +      free_remapped_files(*unsaved_files, i); +      *unsaved_files = 0; +      *num_unsaved_files = 0; +      return -1; +    } + +    /* Determine the length of the file we're remapping to. */ +    fseek(to_file, 0, SEEK_END); +    unsaved->Length = ftell(to_file); +    fseek(to_file, 0, SEEK_SET); +     +    /* Read the contents of the file we're remapping to. */ +    contents = (char *)malloc(unsaved->Length + 1); +    fread(contents, 1, unsaved->Length, to_file); +    contents[unsaved->Length] = 0; +    unsaved->Contents = contents; + +    /* Close the file. */ +    fclose(to_file); +     +    /* Copy the file name that we're remapping from. */ +    filename_len = semi - arg_string; +    filename = (char *)malloc(filename_len + 1); +    memcpy(filename, arg_string, filename_len); +    filename[filename_len] = 0; +    unsaved->Filename = filename; +  } + +  return 0; +} +  int perform_code_completion(int argc, const char **argv) {    const char *input = argv[1];    char *filename = 0; @@ -396,17 +486,26 @@ int perform_code_completion(int argc, const char **argv) {    unsigned column;    CXIndex CIdx;    int errorCode; +  struct CXUnsavedFile *unsaved_files = 0; +  int num_unsaved_files = 0;    input += strlen("-code-completion-at=");    if ((errorCode = parse_file_line_column(input, &filename, &line, &column)))      return errorCode; +  if (parse_remapped_files(argc, argv, 2, &unsaved_files, &num_unsaved_files)) +    return -1; +    CIdx = clang_createIndex(0, 0); -  clang_codeComplete(CIdx, argv[argc - 1], argc - 3, argv + 2,  +  clang_codeComplete(CIdx, argv[argc - 1], argc - num_unsaved_files - 3,  +                     argv + num_unsaved_files + 2,  +                     num_unsaved_files, unsaved_files,                       filename, line, column, &print_completion_result, stdout);    clang_disposeIndex(CIdx);    free(filename); +  free_remapped_files(unsaved_files, num_unsaved_files); +    return 0;  } diff --git a/tools/clang-cc/CMakeLists.txt b/tools/clang-cc/CMakeLists.txt deleted file mode 100644 index c96e8b1d068b..000000000000 --- a/tools/clang-cc/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -set(LLVM_NO_RTTI 1) - -set( LLVM_USED_LIBS -  clangDriver -  clangFrontend -  clangCodeGen -  clangAnalysis -  clangRewrite -  clangSema -  clangAST -  clangParse -  clangLex -  clangBasic -  ) - -set( LLVM_LINK_COMPONENTS -  ${LLVM_TARGETS_TO_BUILD} -  bitreader -  bitwriter -  codegen -  ipo -  selectiondag -  ) - -add_clang_executable(clang-cc -  clang-cc.cpp -  Options.cpp -  ) -add_dependencies(clang-cc clang-headers) - -install(TARGETS clang-cc -  RUNTIME DESTINATION libexec) diff --git a/tools/clang-cc/Makefile b/tools/clang-cc/Makefile deleted file mode 100644 index ebcc1d5fa0ba..000000000000 --- a/tools/clang-cc/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -##===- tools/clang-cc/Makefile -----------------------------*- Makefile -*-===## -#  -#                     The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -#  -##===----------------------------------------------------------------------===## -LEVEL = ../../../.. - -TOOLNAME = clang-cc -CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include -CXXFLAGS = -fno-rtti - -# Clang has no plugins, optimize startup time. -TOOL_NO_EXPORTS = 1 - -# Include this here so we can get the configuration of the targets -# that have been configured for construction. We have to do this  -# early so we can set up LINK_COMPONENTS before including Makefile.rules -include $(LEVEL)/Makefile.config - -LINK_COMPONENTS := $(TARGETS_TO_BUILD) bitreader bitwriter codegen ipo selectiondag -USEDLIBS = clangDriver.a clangFrontend.a clangCodeGen.a clangAnalysis.a	\ -           clangRewrite.a clangSema.a clangAST.a clangParse.a 		\ -           clangLex.a clangBasic.a  - -# clang-cc lives in a special location; we can get away with this -# because nothing else gets installed from here. -PROJ_bindir := $(DESTDIR)$(PROJ_prefix)/libexec - -include $(LLVM_SRC_ROOT)/Makefile.rules diff --git a/tools/clang-cc/Options.cpp b/tools/clang-cc/Options.cpp deleted file mode 100644 index a18598ef7c21..000000000000 --- a/tools/clang-cc/Options.cpp +++ /dev/null @@ -1,1265 +0,0 @@ -//===--- Options.cpp - clang-cc Option Handling ---------------------------===// -// -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// This file contains "pure" option handling, it is only responsible for turning -// the options into internal *Option classes, but shouldn't have any other -// logic. - -#include "Options.h" -#include "clang/Basic/LangOptions.h" -#include "clang/Basic/TargetInfo.h" -#include "clang/Basic/TargetOptions.h" -#include "clang/Frontend/AnalysisConsumer.h" -#include "clang/CodeGen/CodeGenOptions.h" -#include "clang/Frontend/DependencyOutputOptions.h" -#include "clang/Frontend/DiagnosticOptions.h" -#include "clang/Frontend/FrontendOptions.h" -#include "clang/Frontend/HeaderSearchOptions.h" -#include "clang/Frontend/LangStandard.h" -#include "clang/Frontend/PCHReader.h" -#include "clang/Frontend/PreprocessorOptions.h" -#include "clang/Frontend/PreprocessorOutputOptions.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/RegistryParser.h" -#include "llvm/System/Host.h" -#include <stdio.h> - -using namespace clang; - -//===----------------------------------------------------------------------===// -// Analyzer Options -//===----------------------------------------------------------------------===// - -namespace analyzeroptions { - -static llvm::cl::list<Analyses> -AnalysisList(llvm::cl::desc("Source Code Analysis - Checks and Analyses"), -llvm::cl::values( -#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)\ -clEnumValN(NAME, CMDFLAG, DESC), -#include "clang/Frontend/Analyses.def" -clEnumValEnd)); - -static llvm::cl::opt<AnalysisStores> -AnalysisStoreOpt("analyzer-store", -  llvm::cl::desc("Source Code Analysis - Abstract Memory Store Models"), -  llvm::cl::init(BasicStoreModel), -  llvm::cl::values( -#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN)\ -clEnumValN(NAME##Model, CMDFLAG, DESC), -#include "clang/Frontend/Analyses.def" -clEnumValEnd)); - -static llvm::cl::opt<AnalysisConstraints> -AnalysisConstraintsOpt("analyzer-constraints", -  llvm::cl::desc("Source Code Analysis - Symbolic Constraint Engines"), -  llvm::cl::init(RangeConstraintsModel), -  llvm::cl::values( -#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN)\ -clEnumValN(NAME##Model, CMDFLAG, DESC), -#include "clang/Frontend/Analyses.def" -clEnumValEnd)); - -static llvm::cl::opt<AnalysisDiagClients> -AnalysisDiagOpt("analyzer-output", -                llvm::cl::desc("Source Code Analysis - Output Options"), -                llvm::cl::init(PD_HTML), -                llvm::cl::values( -#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREATE)\ -clEnumValN(PD_##NAME, CMDFLAG, DESC), -#include "clang/Frontend/Analyses.def" -clEnumValEnd)); - -static llvm::cl::opt<bool> -AnalyzeAll("analyzer-opt-analyze-headers", -    llvm::cl::desc("Force the static analyzer to analyze " -                   "functions defined in header files")); - -static llvm::cl::opt<bool> -AnalyzerDisplayProgress("analyzer-display-progress", -          llvm::cl::desc("Emit verbose output about the analyzer's progress")); - -static llvm::cl::opt<bool> -AnalyzerExperimentalChecks("analyzer-experimental-checks", -          llvm::cl::desc("Use experimental path-sensitive checks")); - -static llvm::cl::opt<bool> -AnalyzerExperimentalInternalChecks("analyzer-experimental-internal-checks", -  llvm::cl::desc("Use new default path-sensitive checks currently in testing")); - -static llvm::cl::opt<std::string> -AnalyzeSpecificFunction("analyze-function", -               llvm::cl::desc("Run analysis on specific function")); - -static llvm::cl::opt<bool> -EagerlyAssume("analyzer-eagerly-assume", -              llvm::cl::desc("Eagerly assume the truth/falseness of some " -                             "symbolic constraints")); - -static llvm::cl::opt<bool> -NoPurgeDead("analyzer-no-purge-dead", -          llvm::cl::desc("Don't remove dead symbols, bindings, and constraints before" -                         " processing a statement")); - -static llvm::cl::opt<bool> -TrimGraph("trim-egraph", -     llvm::cl::desc("Only show error-related paths in the analysis graph")); - -static llvm::cl::opt<bool> -VisualizeEGDot("analyzer-viz-egraph-graphviz", -               llvm::cl::desc("Display exploded graph using GraphViz")); - -static llvm::cl::opt<bool> -VisualizeEGUbi("analyzer-viz-egraph-ubigraph", -               llvm::cl::desc("Display exploded graph using Ubigraph")); - -} - -//===----------------------------------------------------------------------===// -// Code Generation Options -//===----------------------------------------------------------------------===// - -namespace codegenoptions { - -static llvm::cl::opt<bool> -DisableLLVMOptimizations("disable-llvm-optzns", -                         llvm::cl::desc("Don't run LLVM optimization passes")); - -static llvm::cl::opt<bool> -DisableRedZone("disable-red-zone", -               llvm::cl::desc("Do not emit code that uses the red zone.")); - -static llvm::cl::opt<bool> -GenerateDebugInfo("g", -                  llvm::cl::desc("Generate source level debug information")); - -static llvm::cl::opt<bool> -MAsmVerbose("masm-verbose", llvm::cl::desc("Generate verbose assembly output")); - -static llvm::cl::opt<std::string> -MCodeModel("mcode-model", llvm::cl::desc("The code model to use")); - -static llvm::cl::opt<std::string> -MDebugPass("mdebu-pass", llvm::cl::desc("Output additional debug information")); - -static llvm::cl::opt<bool> -MDisableFPElim("mdisable-fp-elim", -              llvm::cl::desc("Disable frame pointer elimination optimization")); - -static llvm::cl::opt<std::string> -MFloatABI("mfloat-abi", llvm::cl::desc("The float ABI to use")); - -static llvm::cl::opt<std::string> -MLimitFloatPrecision("mlimit-float-precision", -                    llvm::cl::desc("Limit float precision to the given value")); - -static llvm::cl::opt<bool> -MNoZeroInitializedInBSS("mno-zero-initialized-in-bss", -                 llvm::cl::desc("Do not put zero initialized data in the BSS")); - -static llvm::cl::opt<bool> -MSoftFloat("msoft-float", llvm::cl::desc("Use software floating point")); - -static llvm::cl::opt<std::string> -MRelocationModel("mrelocation-model", -                 llvm::cl::desc("The relocation model to use"), -                 llvm::cl::init("pic")); - -static llvm::cl::opt<bool> -MUnwindTables("munwind-tables", -              llvm::cl::desc("Generate unwinding tables for all functions")); - -static llvm::cl::opt<std::string> -MainFileName("main-file-name", -             llvm::cl::desc("Main file name to use for debug info")); - -static llvm::cl::opt<bool> -NoCommon("fno-common", -         llvm::cl::desc("Compile common globals like normal definitions"), -         llvm::cl::ValueDisallowed); - -static llvm::cl::opt<bool> -NoImplicitFloat("no-implicit-float", -  llvm::cl::desc("Don't generate implicit floating point instructions (x86-only)")); - -static llvm::cl::opt<bool> -NoMergeConstants("fno-merge-all-constants", -                       llvm::cl::desc("Disallow merging of constants.")); - -// It might be nice to add bounds to the CommandLine library directly. -struct OptLevelParser : public llvm::cl::parser<unsigned> { -  bool parse(llvm::cl::Option &O, llvm::StringRef ArgName, -             llvm::StringRef Arg, unsigned &Val) { -    if (llvm::cl::parser<unsigned>::parse(O, ArgName, Arg, Val)) -      return true; -    if (Val > 3) -      return O.error("'" + Arg + "' invalid optimization level!"); -    return false; -  } -}; -static llvm::cl::opt<unsigned, false, OptLevelParser> -OptLevel("O", llvm::cl::Prefix, -         llvm::cl::desc("Optimization level")); - -static llvm::cl::opt<bool> -OptSize("Os", llvm::cl::desc("Optimize for size")); - -} - -//===----------------------------------------------------------------------===// -// Dependency Output Options -//===----------------------------------------------------------------------===// - -namespace dependencyoutputoptions { - -static llvm::cl::opt<std::string> -DependencyFile("dependency-file", -               llvm::cl::desc("Filename (or -) to write dependency output to")); - -static llvm::cl::opt<bool> -DependenciesIncludeSystemHeaders("sys-header-deps", -                 llvm::cl::desc("Include system headers in dependency output")); - -static llvm::cl::list<std::string> -DependencyTargets("MT", -         llvm::cl::desc("Specify target for dependency")); - -static llvm::cl::opt<bool> -PhonyDependencyTarget("MP", -            llvm::cl::desc("Create phony target for each dependency " -                           "(other than main file)")); - -} - -//===----------------------------------------------------------------------===// -// Diagnostic Options -//===----------------------------------------------------------------------===// - -namespace diagnosticoptions { - -static llvm::cl::opt<std::string> -DumpBuildInformation("dump-build-information", -                     llvm::cl::value_desc("filename"), -          llvm::cl::desc("output a dump of some build information to a file")); - -static llvm::cl::opt<bool> -NoShowColumn("fno-show-column", -             llvm::cl::desc("Do not include column number on diagnostics")); - -static llvm::cl::opt<bool> -NoShowLocation("fno-show-source-location", -               llvm::cl::desc("Do not include source location information with" -                              " diagnostics")); - -static llvm::cl::opt<bool> -NoCaretDiagnostics("fno-caret-diagnostics", -                   llvm::cl::desc("Do not include source line and caret with" -                                  " diagnostics")); - -static llvm::cl::opt<bool> -NoDiagnosticsFixIt("fno-diagnostics-fixit-info", -                   llvm::cl::desc("Do not include fixit information in" -                                  " diagnostics")); - -static llvm::cl::opt<bool> OptNoWarnings("w"); - -static llvm::cl::opt<bool> OptPedantic("pedantic"); - -static llvm::cl::opt<bool> OptPedanticErrors("pedantic-errors"); - -// This gets all -W options, including -Werror, -W[no-]system-headers, etc.  The -// driver has stripped off -Wa,foo etc.  The driver has also translated -W to -// -Wextra, so we don't need to worry about it. -static llvm::cl::list<std::string> -OptWarnings("W", llvm::cl::Prefix, llvm::cl::ValueOptional); - -static llvm::cl::opt<bool> -PrintSourceRangeInfo("fdiagnostics-print-source-range-info", -                     llvm::cl::desc("Print source range spans in numeric form")); - -static llvm::cl::opt<bool> -PrintDiagnosticOption("fdiagnostics-show-option", -             llvm::cl::desc("Print diagnostic name with mappable diagnostics")); - -static llvm::cl::opt<unsigned> -MessageLength("fmessage-length", -              llvm::cl::desc("Format message diagnostics so that they fit " -                             "within N columns or fewer, when possible."), -              llvm::cl::value_desc("N")); - -static llvm::cl::opt<bool> -PrintColorDiagnostic("fcolor-diagnostics", -                     llvm::cl::desc("Use colors in diagnostics")); - -static llvm::cl::opt<bool> -SilenceRewriteMacroWarning("Wno-rewrite-macros", -                           llvm::cl::desc("Silence ObjC rewriting warnings")); - -static llvm::cl::opt<bool> -VerifyDiagnostics("verify", -                  llvm::cl::desc("Verify emitted diagnostics and warnings")); - -} - -//===----------------------------------------------------------------------===// -// Frontend Options -//===----------------------------------------------------------------------===// - -namespace frontendoptions { - -using namespace clang::frontend; - -static llvm::cl::opt<ParsedSourceLocation> -CodeCompletionAt("code-completion-at", -                 llvm::cl::value_desc("file:line:column"), -              llvm::cl::desc("Dump code-completion information at a location")); - -static llvm::cl::opt<bool> -NoCodeCompletionDebugPrinter("no-code-completion-debug-printer", -                      llvm::cl::desc("Don't the \"debug\" code-completion print")); - -static llvm::cl::opt<bool> -CodeCompletionWantsMacros("code-completion-macros", -                 llvm::cl::desc("Include macros in code-completion results")); - -static llvm::cl::opt<bool> -DisableFree("disable-free", -           llvm::cl::desc("Disable freeing of memory on exit")); - -static llvm::cl::opt<bool> -EmptyInputOnly("empty-input-only", -      llvm::cl::desc("Force running on an empty input file")); - -static llvm::cl::opt<FrontendOptions::InputKind> -InputType("x", llvm::cl::desc("Input language type"), -         llvm::cl::init(FrontendOptions::IK_None), -   llvm::cl::values(clEnumValN(FrontendOptions::IK_C,     "c", "C"), -                    clEnumValN(FrontendOptions::IK_OpenCL,   "cl", "OpenCL C"), -                    clEnumValN(FrontendOptions::IK_CXX,   "c++", "C++"), -                    clEnumValN(FrontendOptions::IK_ObjC,  "objective-c", -                               "Objective C"), -                    clEnumValN(FrontendOptions::IK_ObjCXX, "objective-c++", -                               "Objective C++"), -                    clEnumValN(FrontendOptions::IK_PreprocessedC, -                               "cpp-output", -                               "Preprocessed C"), -                    clEnumValN(FrontendOptions::IK_Asm, -                               "assembler-with-cpp", -                               "Assembly Source Codde"), -                    clEnumValN(FrontendOptions::IK_PreprocessedCXX, -                               "c++-cpp-output", -                               "Preprocessed C++"), -                    clEnumValN(FrontendOptions::IK_PreprocessedObjC, -                               "objective-c-cpp-output", -                               "Preprocessed Objective C"), -                    clEnumValN(FrontendOptions::IK_PreprocessedObjCXX, -                               "objective-c++-cpp-output", -                               "Preprocessed Objective C++"), -                    clEnumValN(FrontendOptions::IK_C, "c-header", -                               "C header"), -                    clEnumValN(FrontendOptions::IK_ObjC, "objective-c-header", -                               "Objective-C header"), -                    clEnumValN(FrontendOptions::IK_CXX, "c++-header", -                               "C++ header"), -                    clEnumValN(FrontendOptions::IK_ObjCXX, -                               "objective-c++-header", -                               "Objective-C++ header"), -                    clEnumValN(FrontendOptions::IK_AST, "ast", -                               "Clang AST"), -                    clEnumValEnd)); - -static llvm::cl::list<std::string> -InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input files>")); - -static llvm::cl::opt<std::string> -InheritanceViewCls("cxx-inheritance-view", -                   llvm::cl::value_desc("class name"), -                  llvm::cl::desc("View C++ inheritance for a specified class")); - -static llvm::cl::list<ParsedSourceLocation> -FixItAtLocations("fixit-at", llvm::cl::value_desc("source-location"), -   llvm::cl::desc("Perform Fix-It modifications at the given source location")); - -static llvm::cl::opt<std::string> -OutputFile("o", - llvm::cl::value_desc("path"), - llvm::cl::desc("Specify output file")); - -static llvm::cl::opt<std::string> -PluginActionName("plugin", -                 llvm::cl::desc("Use the named plugin action " -                                "(use \"help\" to list available options)")); - -static llvm::cl::opt<ActionKind> -ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore, -           llvm::cl::init(ParseSyntaxOnly), -           llvm::cl::values( -             clEnumValN(RunPreprocessorOnly, "Eonly", -                        "Just run preprocessor, no output (for timings)"), -             clEnumValN(PrintPreprocessedInput, "E", -                        "Run preprocessor, emit preprocessed file"), -             clEnumValN(DumpRawTokens, "dump-raw-tokens", -                        "Lex file in raw mode and dump raw tokens"), -             clEnumValN(RunAnalysis, "analyze", -                        "Run static analysis engine"), -             clEnumValN(DumpTokens, "dump-tokens", -                        "Run preprocessor, dump internal rep of tokens"), -             clEnumValN(ParseNoop, "parse-noop", -                        "Run parser with noop callbacks (for timings)"), -             clEnumValN(ParseSyntaxOnly, "fsyntax-only", -                        "Run parser and perform semantic analysis"), -             clEnumValN(FixIt, "fixit", -                        "Apply fix-it advice to the input source"), -             clEnumValN(ParsePrintCallbacks, "parse-print-callbacks", -                        "Run parser and print each callback invoked"), -             clEnumValN(EmitHTML, "emit-html", -                        "Output input source as HTML"), -             clEnumValN(ASTPrint, "ast-print", -                        "Build ASTs and then pretty-print them"), -             clEnumValN(ASTPrintXML, "ast-print-xml", -                        "Build ASTs and then print them in XML format"), -             clEnumValN(ASTDump, "ast-dump", -                        "Build ASTs and then debug dump them"), -             clEnumValN(ASTView, "ast-view", -                        "Build ASTs and view them with GraphViz"), -             clEnumValN(PrintDeclContext, "print-decl-contexts", -                        "Print DeclContexts and their Decls"), -             clEnumValN(DumpRecordLayouts, "dump-record-layouts", -                        "Dump record layout information"), -             clEnumValN(GeneratePTH, "emit-pth", -                        "Generate pre-tokenized header file"), -             clEnumValN(GeneratePCH, "emit-pch", -                        "Generate pre-compiled header file"), -             clEnumValN(EmitAssembly, "S", -                        "Emit native assembly code"), -             clEnumValN(EmitLLVM, "emit-llvm", -                        "Build ASTs then convert to LLVM, emit .ll file"), -             clEnumValN(EmitBC, "emit-llvm-bc", -                        "Build ASTs then convert to LLVM, emit .bc file"), -             clEnumValN(EmitLLVMOnly, "emit-llvm-only", -                        "Build ASTs and convert to LLVM, discarding output"), -             clEnumValN(RewriteTest, "rewrite-test", -                        "Rewriter playground"), -             clEnumValN(RewriteObjC, "rewrite-objc", -                        "Rewrite ObjC into C (code rewriter example)"), -             clEnumValN(RewriteMacros, "rewrite-macros", -                        "Expand macros without full preprocessing"), -             clEnumValN(RewriteBlocks, "rewrite-blocks", -                        "Rewrite Blocks to C"), -             clEnumValEnd)); - -static llvm::cl::opt<bool> -RelocatablePCH("relocatable-pch", -               llvm::cl::desc("Whether to build a relocatable precompiled " -                              "header")); -static llvm::cl::opt<bool> -Stats("print-stats", -      llvm::cl::desc("Print performance metrics and statistics")); - -static llvm::cl::opt<bool> -TimeReport("ftime-report", -           llvm::cl::desc("Print the amount of time each " -                          "phase of compilation takes")); - -} - -//===----------------------------------------------------------------------===// -// Language Options -//===----------------------------------------------------------------------===// - -namespace langoptions { - -using namespace clang::frontend; - -static llvm::cl::opt<bool> -NoBuiltin("fno-builtin", -          llvm::cl::desc("Disable implicit builtin knowledge of functions")); - -static llvm::cl::opt<bool> -AltiVec("faltivec", llvm::cl::desc("Enable AltiVec vector initializer syntax")); - -static llvm::cl::opt<bool> -AccessControl("faccess-control", -              llvm::cl::desc("Enable C++ access control")); - -static llvm::cl::opt<bool> -NoSignedChar("fno-signed-char", -    llvm::cl::desc("Char is unsigned")); - -static llvm::cl::opt<bool> -DollarsInIdents("fdollars-in-identifiers", -                llvm::cl::desc("Allow '$' in identifiers")); - -static llvm::cl::opt<bool> -EmitAllDecls("femit-all-decls", -              llvm::cl::desc("Emit all declarations, even if unused")); - -static llvm::cl::opt<bool> -EnableBlocks("fblocks", llvm::cl::desc("enable the 'blocks' language feature")); - -static llvm::cl::opt<bool> -EnableHeinousExtensions("fheinous-gnu-extensions", -   llvm::cl::desc("enable GNU extensions that you really really shouldn't use"), -                        llvm::cl::ValueDisallowed, llvm::cl::Hidden); - -static llvm::cl::opt<bool> -Exceptions("fexceptions", -           llvm::cl::desc("Enable support for exception handling")); - -static llvm::cl::opt<bool> -Freestanding("ffreestanding", -             llvm::cl::desc("Assert that the compilation takes place in a " -                            "freestanding environment")); - -static llvm::cl::opt<bool> -GNURuntime("fgnu-runtime", -            llvm::cl::desc("Generate output compatible with the standard GNU " -                           "Objective-C runtime")); - -static llvm::cl::opt<LangStandard::Kind> -LangStd("std", llvm::cl::desc("Language standard to compile for"), -        llvm::cl::init(LangStandard::lang_unspecified), llvm::cl::values( -#define LANGSTANDARD(id, name, desc, features) \ -          clEnumValN(LangStandard::lang_##id, name, desc), -#include "clang/Frontend/LangStandards.def" -                   clEnumValEnd)); - -static llvm::cl::opt<bool> -MSExtensions("fms-extensions", -             llvm::cl::desc("Accept some non-standard constructs used in " -                            "Microsoft header files ")); - -static llvm::cl::opt<bool> -NoMathErrno("fno-math-errno", -          llvm::cl::desc("Don't require math functions to respect errno")); - -static llvm::cl::opt<bool> -NoElideConstructors("fno-elide-constructors", -                    llvm::cl::desc("Disable C++ copy constructor elision")); - -static llvm::cl::opt<bool> -NoLaxVectorConversions("fno-lax-vector-conversions", -                       llvm::cl::desc("Disallow implicit conversions between " -                                      "vectors with a different number of " -                                      "elements or different element types")); - - -static llvm::cl::opt<bool> -NoOperatorNames("fno-operator-names", -                llvm::cl::desc("Do not treat C++ operator name keywords as " -                               "synonyms for operators")); - -static llvm::cl::opt<std::string> -ObjCConstantStringClass("fconstant-string-class", -                llvm::cl::value_desc("class name"), -                llvm::cl::desc("Specify the class to use for constant " -                               "Objective-C string objects.")); - -static llvm::cl::opt<bool> -ObjCEnableGC("fobjc-gc", -             llvm::cl::desc("Enable Objective-C garbage collection")); - -static llvm::cl::opt<bool> -ObjCExclusiveGC("fobjc-gc-only", -                llvm::cl::desc("Use GC exclusively for Objective-C related " -                               "memory management")); - -static llvm::cl::opt<bool> -ObjCEnableGCBitmapPrint("print-ivar-layout", -             llvm::cl::desc("Enable Objective-C Ivar layout bitmap print trace")); - -static llvm::cl::opt<bool> -ObjCNonFragileABI("fobjc-nonfragile-abi", -                  llvm::cl::desc("enable objective-c's nonfragile abi")); - -static llvm::cl::opt<bool> -OverflowChecking("ftrapv", -                 llvm::cl::desc("Trap on integer overflow")); - -static llvm::cl::opt<unsigned> -PICLevel("pic-level", llvm::cl::desc("Value for __PIC__")); - -static llvm::cl::opt<bool> -PThread("pthread", llvm::cl::desc("Support POSIX threads in generated code")); - -static llvm::cl::opt<bool> -PascalStrings("fpascal-strings", -              llvm::cl::desc("Recognize and construct Pascal-style " -                             "string literals")); - -static llvm::cl::opt<bool> -NoRtti("fno-rtti", -     llvm::cl::desc("Disable generation of rtti information")); - -static llvm::cl::opt<bool> -ShortWChar("fshort-wchar", -    llvm::cl::desc("Force wchar_t to be a short unsigned int")); - -static llvm::cl::opt<bool> -StaticDefine("static-define", llvm::cl::desc("Should __STATIC__ be defined")); - -static llvm::cl::opt<int> -StackProtector("stack-protector", -               llvm::cl::desc("Enable stack protectors")); - -static llvm::cl::opt<LangOptions::VisibilityMode> -SymbolVisibility("fvisibility", -                 llvm::cl::desc("Set the default symbol visibility:"), -                 llvm::cl::init(LangOptions::Default), -                 llvm::cl::values(clEnumValN(LangOptions::Default, "default", -                                             "Use default symbol visibility"), -                                  clEnumValN(LangOptions::Hidden, "hidden", -                                             "Use hidden symbol visibility"), -                                  clEnumValN(LangOptions::Protected,"protected", -                                             "Use protected symbol visibility"), -                                  clEnumValEnd)); - -static llvm::cl::opt<unsigned> -TemplateDepth("ftemplate-depth", -              llvm::cl::desc("Maximum depth of recursive template " -                             "instantiation")); - -static llvm::cl::opt<bool> -Trigraphs("trigraphs", llvm::cl::desc("Process trigraph sequences")); - -static llvm::cl::opt<bool> -WritableStrings("fwritable-strings", -              llvm::cl::desc("Store string literals as writable data")); - -} - -//===----------------------------------------------------------------------===// -// General Preprocessor Options -//===----------------------------------------------------------------------===// - -namespace preprocessoroptions { - -static llvm::cl::list<std::string> -D_macros("D", llvm::cl::value_desc("macro"), llvm::cl::Prefix, -       llvm::cl::desc("Predefine the specified macro")); - -static llvm::cl::list<std::string> -ImplicitIncludes("include", llvm::cl::value_desc("file"), -                 llvm::cl::desc("Include file before parsing")); -static llvm::cl::list<std::string> -ImplicitMacroIncludes("imacros", llvm::cl::value_desc("file"), -                      llvm::cl::desc("Include macros from file before parsing")); - -static llvm::cl::opt<std::string> -ImplicitIncludePCH("include-pch", llvm::cl::value_desc("file"), -                   llvm::cl::desc("Include precompiled header file")); - -static llvm::cl::opt<std::string> -ImplicitIncludePTH("include-pth", llvm::cl::value_desc("file"), -                   llvm::cl::desc("Include file before parsing")); - -static llvm::cl::opt<std::string> -TokenCache("token-cache", llvm::cl::value_desc("path"), -           llvm::cl::desc("Use specified token cache file")); - -static llvm::cl::list<std::string> -U_macros("U", llvm::cl::value_desc("macro"), llvm::cl::Prefix, -         llvm::cl::desc("Undefine the specified macro")); - -static llvm::cl::opt<bool> -UndefMacros("undef", llvm::cl::value_desc("macro"), -            llvm::cl::desc("undef all system defines")); - -} - -//===----------------------------------------------------------------------===// -// Header Search Options -//===----------------------------------------------------------------------===// - -namespace headersearchoptions { - -static llvm::cl::opt<bool> -nostdinc("nostdinc", llvm::cl::desc("Disable standard #include directories")); - -static llvm::cl::opt<bool> -nobuiltininc("nobuiltininc", -             llvm::cl::desc("Disable builtin #include directories")); - -// Various command line options.  These four add directories to each chain. -static llvm::cl::list<std::string> -F_dirs("F", llvm::cl::value_desc("directory"), llvm::cl::Prefix, -       llvm::cl::desc("Add directory to framework include search path")); - -static llvm::cl::list<std::string> -I_dirs("I", llvm::cl::value_desc("directory"), llvm::cl::Prefix, -       llvm::cl::desc("Add directory to include search path")); - -static llvm::cl::list<std::string> -idirafter_dirs("idirafter", llvm::cl::value_desc("directory"), llvm::cl::Prefix, -               llvm::cl::desc("Add directory to AFTER include search path")); - -static llvm::cl::list<std::string> -iquote_dirs("iquote", llvm::cl::value_desc("directory"), llvm::cl::Prefix, -               llvm::cl::desc("Add directory to QUOTE include search path")); - -static llvm::cl::list<std::string> -isystem_dirs("isystem", llvm::cl::value_desc("directory"), llvm::cl::Prefix, -            llvm::cl::desc("Add directory to SYSTEM include search path")); - -// These handle -iprefix/-iwithprefix/-iwithprefixbefore. -static llvm::cl::list<std::string> -iprefix_vals("iprefix", llvm::cl::value_desc("prefix"), llvm::cl::Prefix, -             llvm::cl::desc("Set the -iwithprefix/-iwithprefixbefore prefix")); -static llvm::cl::list<std::string> -iwithprefix_vals("iwithprefix", llvm::cl::value_desc("dir"), llvm::cl::Prefix, -     llvm::cl::desc("Set directory to SYSTEM include search path with prefix")); -static llvm::cl::list<std::string> -iwithprefixbefore_vals("iwithprefixbefore", llvm::cl::value_desc("dir"), -                       llvm::cl::Prefix, -            llvm::cl::desc("Set directory to include search path with prefix")); - -static llvm::cl::opt<std::string> -isysroot("isysroot", llvm::cl::value_desc("dir"), -         llvm::cl::desc("Set the system root directory (usually /)")); - -static llvm::cl::opt<bool> -Verbose("v", llvm::cl::desc("Enable verbose output")); - -} - -//===----------------------------------------------------------------------===// -// Preprocessed Output Options -//===----------------------------------------------------------------------===// - -namespace preprocessoroutputoptions { - -static llvm::cl::opt<bool> -DisableLineMarkers("P", llvm::cl::desc("Disable linemarker output in -E mode")); - -static llvm::cl::opt<bool> -EnableCommentOutput("C", llvm::cl::desc("Enable comment output in -E mode")); - -static llvm::cl::opt<bool> -EnableMacroCommentOutput("CC", -                         llvm::cl::desc("Enable comment output in -E mode, " -                                        "even from macro expansions")); -static llvm::cl::opt<bool> -DumpMacros("dM", llvm::cl::desc("Print macro definitions in -E mode instead of" -                                " normal output")); -static llvm::cl::opt<bool> -DumpDefines("dD", llvm::cl::desc("Print macro definitions in -E mode in " -                                "addition to normal output")); - -} - -//===----------------------------------------------------------------------===// -// Target Options -//===----------------------------------------------------------------------===// - -namespace targetoptions { - -static llvm::cl::opt<std::string> -TargetABI("target-abi", -          llvm::cl::desc("Target a particular ABI type")); - -static llvm::cl::opt<std::string> -TargetCPU("mcpu", -         llvm::cl::desc("Target a specific cpu type ('-mcpu help' for details)")); - -static llvm::cl::list<std::string> -TargetFeatures("target-feature", llvm::cl::desc("Target specific attributes")); - -static llvm::cl::opt<std::string> -TargetTriple("triple", -  llvm::cl::desc("Specify target triple (e.g. i686-apple-darwin9)")); - -} - -//===----------------------------------------------------------------------===// -// Option Object Construction -//===----------------------------------------------------------------------===// - -void clang::InitializeAnalyzerOptions(AnalyzerOptions &Opts) { -  using namespace analyzeroptions; -  Opts.AnalysisList = AnalysisList; -  Opts.AnalysisStoreOpt = AnalysisStoreOpt; -  Opts.AnalysisConstraintsOpt = AnalysisConstraintsOpt; -  Opts.AnalysisDiagOpt = AnalysisDiagOpt; -  Opts.VisualizeEGDot = VisualizeEGDot; -  Opts.VisualizeEGUbi = VisualizeEGUbi; -  Opts.AnalyzeAll = AnalyzeAll; -  Opts.AnalyzerDisplayProgress = AnalyzerDisplayProgress; -  Opts.PurgeDead = !NoPurgeDead; -  Opts.EagerlyAssume = EagerlyAssume; -  Opts.AnalyzeSpecificFunction = AnalyzeSpecificFunction; -  Opts.EnableExperimentalChecks = AnalyzerExperimentalChecks; -  Opts.EnableExperimentalInternalChecks = AnalyzerExperimentalInternalChecks; -  Opts.TrimGraph = TrimGraph; -} - -void clang::InitializeCodeGenOptions(CodeGenOptions &Opts, -                                     const LangOptions &Lang) { -  using namespace codegenoptions; - -  // -Os implies -O2 -  unsigned Opt = OptLevel.getPosition() ? OptLevel : 0; -  Opts.OptimizationLevel = OptSize ? 2 : Opt; - -  // We must always run at least the always inlining pass. -  Opts.Inlining = (Opts.OptimizationLevel > 1) ? CodeGenOptions::NormalInlining -    : CodeGenOptions::OnlyAlwaysInlining; - -  Opts.DebugInfo = GenerateDebugInfo; -  Opts.DisableLLVMOpts = DisableLLVMOptimizations; -  Opts.DisableRedZone = DisableRedZone; -  Opts.MergeAllConstants = !NoMergeConstants; -  Opts.NoCommon = NoCommon; -  Opts.NoImplicitFloat = NoImplicitFloat; -  Opts.OptimizeSize = OptSize; -  Opts.UnrollLoops = (Opts.OptimizationLevel > 1 && !OptSize); - -  // LLVM Code Generator options. - -  Opts.AsmVerbose = MAsmVerbose; -  Opts.CodeModel = MCodeModel; -  Opts.DebugPass = MDebugPass; -  Opts.DisableFPElim = MDisableFPElim; -  Opts.FloatABI = MFloatABI; -  Opts.LimitFloatPrecision = MLimitFloatPrecision; -  Opts.NoZeroInitializedInBSS = MNoZeroInitializedInBSS; -  Opts.SoftFloat = MSoftFloat; -  Opts.RelocationModel = MRelocationModel; -  Opts.UnwindTables = MUnwindTables; - -#ifdef NDEBUG -  Opts.VerifyModule = 0; -#endif - -  if (MainFileName.getPosition()) -    Opts.MainFileName = MainFileName; -} - -void clang::InitializeDependencyOutputOptions(DependencyOutputOptions &Opts) { -  using namespace dependencyoutputoptions; - -  Opts.OutputFile = DependencyFile; -  Opts.Targets = DependencyTargets; -  Opts.IncludeSystemHeaders = DependenciesIncludeSystemHeaders; -  Opts.UsePhonyTargets = PhonyDependencyTarget; -} - -void clang::InitializeDiagnosticOptions(DiagnosticOptions &Opts) { -  using namespace diagnosticoptions; - -  Opts.Warnings = OptWarnings; -  Opts.DumpBuildInformation = DumpBuildInformation; -  Opts.IgnoreWarnings = OptNoWarnings; -  Opts.MessageLength = MessageLength; -  Opts.NoRewriteMacros = SilenceRewriteMacroWarning; -  Opts.Pedantic = OptPedantic; -  Opts.PedanticErrors = OptPedanticErrors; -  Opts.ShowCarets = !NoCaretDiagnostics; -  Opts.ShowColors = PrintColorDiagnostic; -  Opts.ShowColumn = !NoShowColumn; -  Opts.ShowFixits = !NoDiagnosticsFixIt; -  Opts.ShowLocation = !NoShowLocation; -  Opts.ShowOptionNames = PrintDiagnosticOption; -  Opts.ShowSourceRanges = PrintSourceRangeInfo; -  Opts.VerifyDiagnostics = VerifyDiagnostics; -} - -void clang::InitializeFrontendOptions(FrontendOptions &Opts) { -  using namespace frontendoptions; - -  Opts.ProgramAction = ProgAction; -  Opts.ActionName = PluginActionName; -  Opts.CodeCompletionAt = CodeCompletionAt; -  Opts.DebugCodeCompletionPrinter = !NoCodeCompletionDebugPrinter; -  Opts.DisableFree = DisableFree; -  Opts.EmptyInputOnly = EmptyInputOnly; -  Opts.FixItLocations = FixItAtLocations; -  Opts.OutputFile = OutputFile; -  Opts.RelocatablePCH = RelocatablePCH; -  Opts.ShowMacrosInCodeCompletion = CodeCompletionWantsMacros; -  Opts.ShowStats = Stats; -  Opts.ShowTimers = TimeReport; -  Opts.ViewClassInheritance = InheritanceViewCls; - -  // Enforce certain program action implications. -  if (!Opts.ActionName.empty()) -    Opts.ProgramAction = frontend::PluginAction; -  if (!Opts.ViewClassInheritance.empty()) -    Opts.ProgramAction = frontend::InheritanceView; -  if (!Opts.FixItLocations.empty()) -    Opts.ProgramAction = frontend::FixIt; - -  // '-' is the default input if none is given. -  if (InputFilenames.empty()) { -    FrontendOptions::InputKind IK = InputType; -    if (IK == FrontendOptions::IK_None) IK = FrontendOptions::IK_C; -    Opts.Inputs.push_back(std::make_pair(IK, "-")); -  } else { -    for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) { -      FrontendOptions::InputKind IK = InputType; -      llvm::StringRef Ext = -        llvm::StringRef(InputFilenames[i]).rsplit('.').second; -      if (IK == FrontendOptions::IK_None) -        IK = FrontendOptions::getInputKindForExtension(Ext); -      Opts.Inputs.push_back(std::make_pair(IK, InputFilenames[i])); -    } -  } -} - -void clang::InitializeHeaderSearchOptions(HeaderSearchOptions &Opts, -                                          llvm::StringRef BuiltinIncludePath) { -  using namespace headersearchoptions; - -  if (isysroot.getPosition()) -    Opts.Sysroot = isysroot; -  Opts.Verbose = Verbose; - -  // Handle -I... and -F... options, walking the lists in parallel. -  unsigned Iidx = 0, Fidx = 0; -  while (Iidx < I_dirs.size() && Fidx < F_dirs.size()) { -    if (I_dirs.getPosition(Iidx) < F_dirs.getPosition(Fidx)) { -      Opts.AddPath(I_dirs[Iidx], frontend::Angled, true, false); -      ++Iidx; -    } else { -      Opts.AddPath(F_dirs[Fidx], frontend::Angled, true, true); -      ++Fidx; -    } -  } - -  // Consume what's left from whatever list was longer. -  for (; Iidx != I_dirs.size(); ++Iidx) -    Opts.AddPath(I_dirs[Iidx], frontend::Angled, true, false); -  for (; Fidx != F_dirs.size(); ++Fidx) -    Opts.AddPath(F_dirs[Fidx], frontend::Angled, true, true); - -  // Handle -idirafter... options. -  for (unsigned i = 0, e = idirafter_dirs.size(); i != e; ++i) -    Opts.AddPath(idirafter_dirs[i], frontend::After, true, false); - -  // Handle -iquote... options. -  for (unsigned i = 0, e = iquote_dirs.size(); i != e; ++i) -    Opts.AddPath(iquote_dirs[i], frontend::Quoted, true, false); - -  // Handle -isystem... options. -  for (unsigned i = 0, e = isystem_dirs.size(); i != e; ++i) -    Opts.AddPath(isystem_dirs[i], frontend::System, true, false); - -  // Walk the -iprefix/-iwithprefix/-iwithprefixbefore argument lists in -  // parallel, processing the values in order of occurance to get the right -  // prefixes. -  { -    std::string Prefix = "";  // FIXME: this isn't the correct default prefix. -    unsigned iprefix_idx = 0; -    unsigned iwithprefix_idx = 0; -    unsigned iwithprefixbefore_idx = 0; -    bool iprefix_done           = iprefix_vals.empty(); -    bool iwithprefix_done       = iwithprefix_vals.empty(); -    bool iwithprefixbefore_done = iwithprefixbefore_vals.empty(); -    while (!iprefix_done || !iwithprefix_done || !iwithprefixbefore_done) { -      if (!iprefix_done && -          (iwithprefix_done || -           iprefix_vals.getPosition(iprefix_idx) < -           iwithprefix_vals.getPosition(iwithprefix_idx)) && -          (iwithprefixbefore_done || -           iprefix_vals.getPosition(iprefix_idx) < -           iwithprefixbefore_vals.getPosition(iwithprefixbefore_idx))) { -        Prefix = iprefix_vals[iprefix_idx]; -        ++iprefix_idx; -        iprefix_done = iprefix_idx == iprefix_vals.size(); -      } else if (!iwithprefix_done && -                 (iwithprefixbefore_done || -                  iwithprefix_vals.getPosition(iwithprefix_idx) < -                  iwithprefixbefore_vals.getPosition(iwithprefixbefore_idx))) { -        Opts.AddPath(Prefix+iwithprefix_vals[iwithprefix_idx], -                     frontend::System, false, false); -        ++iwithprefix_idx; -        iwithprefix_done = iwithprefix_idx == iwithprefix_vals.size(); -      } else { -        Opts.AddPath(Prefix+iwithprefixbefore_vals[iwithprefixbefore_idx], -                     frontend::Angled, false, false); -        ++iwithprefixbefore_idx; -        iwithprefixbefore_done = -          iwithprefixbefore_idx == iwithprefixbefore_vals.size(); -      } -    } -  } - -  // Add CPATH environment paths. -  if (const char *Env = getenv("CPATH")) -    Opts.EnvIncPath = Env; - -  // Add language specific environment paths. -  if (const char *Env = getenv("OBJCPLUS_INCLUDE_PATH")) -    Opts.ObjCXXEnvIncPath = Env; -  if (const char *Env = getenv("CPLUS_INCLUDE_PATH")) -    Opts.CXXEnvIncPath = Env; -  if (const char *Env = getenv("OBJC_INCLUDE_PATH")) -    Opts.CEnvIncPath = Env; -  if (const char *Env = getenv("C_INCLUDE_PATH")) -    Opts.CEnvIncPath = Env; - -  if (!nobuiltininc) -    Opts.BuiltinIncludePath = BuiltinIncludePath; - -  Opts.UseStandardIncludes = !nostdinc; -} - -void clang::InitializePreprocessorOptions(PreprocessorOptions &Opts) { -  using namespace preprocessoroptions; - -  Opts.ImplicitPCHInclude = ImplicitIncludePCH; -  Opts.ImplicitPTHInclude = ImplicitIncludePTH; - -  // Select the token cache file, we don't support more than one currently so we -  // can't have both an implicit-pth and a token cache file. -  if (TokenCache.getPosition() && ImplicitIncludePTH.getPosition()) { -    // FIXME: Don't fail like this. -    fprintf(stderr, "error: cannot use both -token-cache and -include-pth " -            "options\n"); -    exit(1); -  } -  if (TokenCache.getPosition()) -    Opts.TokenCache = TokenCache; -  else -    Opts.TokenCache = ImplicitIncludePTH; - -  // Use predefines? -  Opts.UsePredefines = !UndefMacros; - -  // Add macros from the command line. -  unsigned d = 0, D = D_macros.size(); -  unsigned u = 0, U = U_macros.size(); -  while (d < D || u < U) { -    if (u == U || (d < D && D_macros.getPosition(d) < U_macros.getPosition(u))) -      Opts.addMacroDef(D_macros[d++]); -    else -      Opts.addMacroUndef(U_macros[u++]); -  } - -  // If -imacros are specified, include them now.  These are processed before -  // any -include directives. -  for (unsigned i = 0, e = ImplicitMacroIncludes.size(); i != e; ++i) -    Opts.MacroIncludes.push_back(ImplicitMacroIncludes[i]); - -  // Add the ordered list of -includes, sorting in the implicit include options -  // at the appropriate location. -  llvm::SmallVector<std::pair<unsigned, std::string*>, 8> OrderedPaths; -  std::string OriginalFile; - -  if (!ImplicitIncludePTH.empty()) -    OrderedPaths.push_back(std::make_pair(ImplicitIncludePTH.getPosition(), -                                          &ImplicitIncludePTH)); -  if (!ImplicitIncludePCH.empty()) { -    OriginalFile = PCHReader::getOriginalSourceFile(ImplicitIncludePCH); -    // FIXME: Don't fail like this. -    if (OriginalFile.empty()) -      exit(1); -    OrderedPaths.push_back(std::make_pair(ImplicitIncludePCH.getPosition(), -                                          &OriginalFile)); -  } -  for (unsigned i = 0, e = ImplicitIncludes.size(); i != e; ++i) -    OrderedPaths.push_back(std::make_pair(ImplicitIncludes.getPosition(i), -                                          &ImplicitIncludes[i])); -  llvm::array_pod_sort(OrderedPaths.begin(), OrderedPaths.end()); - -  for (unsigned i = 0, e = OrderedPaths.size(); i != e; ++i) -    Opts.Includes.push_back(*OrderedPaths[i].second); -} - -void clang::InitializeLangOptions(LangOptions &Options, -                                  FrontendOptions::InputKind IK) { -  using namespace langoptions; - -  // Set some properties which depend soley on the input kind; it would be nice -  // to move these to the language standard, and have the driver resolve the -  // input kind + language standard. -  if (IK == FrontendOptions::IK_Asm) { -    Options.AsmPreprocessor = 1; -  } else if (IK == FrontendOptions::IK_ObjC || -             IK == FrontendOptions::IK_ObjCXX || -             IK == FrontendOptions::IK_PreprocessedObjC || -             IK == FrontendOptions::IK_PreprocessedObjCXX) { -    Options.ObjC1 = Options.ObjC2 = 1; -  } - -  if (LangStd == LangStandard::lang_unspecified) { -    // Based on the base language, pick one. -    switch (IK) { -    case FrontendOptions::IK_None: -    case FrontendOptions::IK_AST: -      assert(0 && "Invalid input kind!"); -    case FrontendOptions::IK_OpenCL: -      LangStd = LangStandard::lang_opencl; -      break; -    case FrontendOptions::IK_Asm: -    case FrontendOptions::IK_C: -    case FrontendOptions::IK_PreprocessedC: -    case FrontendOptions::IK_ObjC: -    case FrontendOptions::IK_PreprocessedObjC: -      LangStd = LangStandard::lang_gnu99; -      break; -    case FrontendOptions::IK_CXX: -    case FrontendOptions::IK_PreprocessedCXX: -    case FrontendOptions::IK_ObjCXX: -    case FrontendOptions::IK_PreprocessedObjCXX: -      LangStd = LangStandard::lang_gnucxx98; -      break; -    } -  } - -  const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd); -  Options.BCPLComment = Std.hasBCPLComments(); -  Options.C99 = Std.isC99(); -  Options.CPlusPlus = Std.isCPlusPlus(); -  Options.CPlusPlus0x = Std.isCPlusPlus0x(); -  Options.Digraphs = Std.hasDigraphs(); -  Options.GNUInline = !Std.isC99(); -  Options.GNUMode = Std.isGNUMode(); -  Options.HexFloats = Std.hasHexFloats(); -  Options.ImplicitInt = Std.hasImplicitInt(); - -  // OpenCL has some additional defaults. -  if (LangStd == LangStandard::lang_opencl) { -    Options.OpenCL = 1; -    Options.AltiVec = 1; -    Options.CXXOperatorNames = 1; -    Options.LaxVectorConversions = 1; -  } - -  // OpenCL and C++ both have bool, true, false keywords. -  Options.Bool = Options.OpenCL || Options.CPlusPlus; - -  if (Options.CPlusPlus) -    Options.CXXOperatorNames = !NoOperatorNames; - -  if (ObjCExclusiveGC) -    Options.setGCMode(LangOptions::GCOnly); -  else if (ObjCEnableGC) -    Options.setGCMode(LangOptions::HybridGC); - -  if (ObjCEnableGCBitmapPrint) -    Options.ObjCGCBitmapPrint = 1; - -  if (AltiVec) -    Options.AltiVec = 1; - -  if (PThread) -    Options.POSIXThreads = 1; - -  Options.setVisibilityMode(SymbolVisibility); -  Options.OverflowChecking = OverflowChecking; - -  // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs -  // is specified, or -std is set to a conforming mode. -  Options.Trigraphs = !Options.GNUMode; -  if (Trigraphs.getPosition()) -    Options.Trigraphs = Trigraphs;  // Command line option wins if specified. - -  // Default to not accepting '$' in identifiers when preprocessing assembler. -  Options.DollarIdents = !Options.AsmPreprocessor; -  if (DollarsInIdents.getPosition())  // Explicit setting overrides default. -    Options.DollarIdents = DollarsInIdents; - -  if (PascalStrings.getPosition()) -    Options.PascalStrings = PascalStrings; -  if (MSExtensions.getPosition()) -    Options.Microsoft = MSExtensions; -  Options.WritableStrings = WritableStrings; -  if (NoLaxVectorConversions.getPosition()) -      Options.LaxVectorConversions = 0; -  Options.Exceptions = Exceptions; -  Options.Rtti = !NoRtti; -  Options.Blocks = EnableBlocks; -  Options.CharIsSigned = !NoSignedChar; -  if (ShortWChar.getPosition()) -    Options.ShortWChar = ShortWChar; - -  Options.NoBuiltin = NoBuiltin; -  if (Freestanding) -    Options.Freestanding = Options.NoBuiltin = 1; - -  if (EnableHeinousExtensions) -    Options.HeinousExtensions = 1; - -  if (AccessControl) -    Options.AccessControl = 1; - -  Options.ElideConstructors = !NoElideConstructors; - -  Options.MathErrno = !NoMathErrno; - -  if (TemplateDepth.getPosition()) -    Options.InstantiationDepth = TemplateDepth; - -  // Override the default runtime if the user requested it. -  if (GNURuntime) -    Options.NeXTRuntime = 0; - -  if (!ObjCConstantStringClass.empty()) -    Options.ObjCConstantStringClass = ObjCConstantStringClass; - -  if (ObjCNonFragileABI) -    Options.ObjCNonFragileABI = 1; - -  if (EmitAllDecls) -    Options.EmitAllDecls = 1; - -  // The __OPTIMIZE_SIZE__ define is tied to -Oz, which we don't support. -  unsigned Opt = -    codegenoptions::OptLevel.getPosition() ? codegenoptions::OptLevel : 0; -  Options.OptimizeSize = 0; -  Options.Optimize = codegenoptions::OptSize || Opt; - -  assert(PICLevel <= 2 && "Invalid value for -pic-level"); -  Options.PICLevel = PICLevel; - -  // This is the __NO_INLINE__ define, which just depends on things like the -  // optimization level and -fno-inline, not actually whether the backend has -  // inlining enabled. -  // -  // FIXME: This is affected by other options (-fno-inline). -  Options.NoInline = !Opt; - -  Options.Static = StaticDefine; - -  if (StackProtector.getPosition()) { -    switch (StackProtector) { -    default: -      assert(0 && "Invalid value for -stack-protector"); -    case 0: Options.setStackProtectorMode(LangOptions::SSPOff); break; -    case 1: Options.setStackProtectorMode(LangOptions::SSPOn);  break; -    case 2: Options.setStackProtectorMode(LangOptions::SSPReq); break; -    } -  } -} - -void -clang::InitializePreprocessorOutputOptions(PreprocessorOutputOptions &Opts) { -  using namespace preprocessoroutputoptions; - -  Opts.ShowCPP = !DumpMacros; -  Opts.ShowMacros = DumpMacros || DumpDefines; -  Opts.ShowLineMarkers = !DisableLineMarkers; -  Opts.ShowComments = EnableCommentOutput; -  Opts.ShowMacroComments = EnableMacroCommentOutput; -} - -void clang::InitializeTargetOptions(TargetOptions &Opts) { -  using namespace targetoptions; - -  Opts.ABI = TargetABI; -  Opts.CPU = TargetCPU; -  Opts.Triple = TargetTriple; -  Opts.Features = TargetFeatures; - -  // Use the host triple if unspecified. -  if (Opts.Triple.empty()) -    Opts.Triple = llvm::sys::getHostTriple(); -} diff --git a/tools/clang-cc/Options.h b/tools/clang-cc/Options.h deleted file mode 100644 index 91e37f261103..000000000000 --- a/tools/clang-cc/Options.h +++ /dev/null @@ -1,54 +0,0 @@ -//===-- Options.h - clang-cc Option Handling --------------------*- C++ -*-===// -// -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANGCC_OPTIONS_H -#define LLVM_CLANGCC_OPTIONS_H - -#include "clang/Frontend/FrontendOptions.h" -#include "llvm/ADT/StringRef.h" - -namespace clang { - -class AnalyzerOptions; -class CodeGenOptions; -class DependencyOutputOptions; -class DiagnosticOptions; -class FrontendOptions; -class HeaderSearchOptions; -class LangOptions; -class PreprocessorOptions; -class PreprocessorOutputOptions; -class TargetInfo; -class TargetOptions; - -void InitializeAnalyzerOptions(AnalyzerOptions &Opts); - -void InitializeCodeGenOptions(CodeGenOptions &Opts, -                              const LangOptions &Lang); - -void InitializeDependencyOutputOptions(DependencyOutputOptions &Opts); - -void InitializeDiagnosticOptions(DiagnosticOptions &Opts); - -void InitializeFrontendOptions(FrontendOptions &Opts); - -void InitializeHeaderSearchOptions(HeaderSearchOptions &Opts, -                                   llvm::StringRef BuiltinIncludePath); - -void InitializeLangOptions(LangOptions &Options, FrontendOptions::InputKind LK); - -void InitializePreprocessorOptions(PreprocessorOptions &Opts); - -void InitializePreprocessorOutputOptions(PreprocessorOutputOptions &Opts); - -void InitializeTargetOptions(TargetOptions &Opts); - -} // end namespace clang - -#endif diff --git a/tools/clang-cc/clang-cc.cpp b/tools/clang-cc/clang-cc.cpp deleted file mode 100644 index 2899684284a9..000000000000 --- a/tools/clang-cc/clang-cc.cpp +++ /dev/null @@ -1,408 +0,0 @@ -//===--- clang.cpp - C-Language Front-end ---------------------------------===// -// -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -//  This utility may be invoked in the following manner: -//   clang-cc --help                - Output help info. -//   clang-cc [options]             - Read from stdin. -//   clang-cc [options] file        - Read from "file". -//   clang-cc [options] file1 file2 - Read these files. -// -//===----------------------------------------------------------------------===// - -#include "Options.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/FileManager.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/TargetInfo.h" -#include "clang/Basic/Version.h" -#include "clang/Driver/Arg.h" -#include "clang/Driver/ArgList.h" -#include "clang/Driver/CC1Options.h" -#include "clang/Driver/DriverDiagnostic.h" -#include "clang/Driver/OptTable.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/CompilerInvocation.h" -#include "clang/Frontend/FrontendActions.h" -#include "clang/Frontend/FrontendDiagnostic.h" -#include "clang/Frontend/FrontendPluginRegistry.h" -#include "clang/Frontend/TextDiagnosticBuffer.h" -#include "clang/Frontend/TextDiagnosticPrinter.h" -#include "clang/Frontend/VerifyDiagnosticsClient.h" -#include "llvm/LLVMContext.h" -#include "llvm/ADT/OwningPtr.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/PluginLoader.h" -#include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/Timer.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Host.h" -#include "llvm/System/Path.h" -#include "llvm/System/Signals.h" -#include "llvm/Target/TargetSelect.h" -#include <cstdio> -using namespace clang; - -//===----------------------------------------------------------------------===// -// Main driver -//===----------------------------------------------------------------------===// - -std::string GetBuiltinIncludePath(const char *Argv0) { -  llvm::sys::Path P = -    llvm::sys::Path::GetMainExecutable(Argv0, -                                       (void*)(intptr_t) GetBuiltinIncludePath); - -  if (!P.isEmpty()) { -    P.eraseComponent();  // Remove /clang from foo/bin/clang -    P.eraseComponent();  // Remove /bin   from foo/bin - -    // Get foo/lib/clang/<version>/include -    P.appendComponent("lib"); -    P.appendComponent("clang"); -    P.appendComponent(CLANG_VERSION_STRING); -    P.appendComponent("include"); -  } - -  return P.str(); -} - -static void LLVMErrorHandler(void *UserData, const std::string &Message) { -  Diagnostic &Diags = *static_cast<Diagnostic*>(UserData); - -  Diags.Report(diag::err_fe_error_backend) << Message; - -  // We cannot recover from llvm errors. -  exit(1); -} - -static FrontendAction *CreateFrontendAction(CompilerInstance &CI) { -  using namespace clang::frontend; - -  switch (CI.getFrontendOpts().ProgramAction) { -  default: -    llvm::llvm_unreachable("Invalid program action!"); - -  case ASTDump:                return new ASTDumpAction(); -  case ASTPrint:               return new ASTPrintAction(); -  case ASTPrintXML:            return new ASTPrintXMLAction(); -  case ASTView:                return new ASTViewAction(); -  case DumpRawTokens:          return new DumpRawTokensAction(); -  case DumpRecordLayouts:      return new DumpRecordAction(); -  case DumpTokens:             return new DumpTokensAction(); -  case EmitAssembly:           return new EmitAssemblyAction(); -  case EmitBC:                 return new EmitBCAction(); -  case EmitHTML:               return new HTMLPrintAction(); -  case EmitLLVM:               return new EmitLLVMAction(); -  case EmitLLVMOnly:           return new EmitLLVMOnlyAction(); -  case FixIt:                  return new FixItAction(); -  case GeneratePCH:            return new GeneratePCHAction(); -  case GeneratePTH:            return new GeneratePTHAction(); -  case InheritanceView:        return new InheritanceViewAction(); -  case ParseNoop:              return new ParseOnlyAction(); -  case ParsePrintCallbacks:    return new PrintParseAction(); -  case ParseSyntaxOnly:        return new SyntaxOnlyAction(); - -  case PluginAction: { -    if (CI.getFrontendOpts().ActionName == "help") { -      llvm::errs() << "clang-cc plugins:\n"; -      for (FrontendPluginRegistry::iterator it = -             FrontendPluginRegistry::begin(), -             ie = FrontendPluginRegistry::end(); -           it != ie; ++it) -        llvm::errs() << "  " << it->getName() << " - " << it->getDesc() << "\n"; -      exit(1); -    } - -    for (FrontendPluginRegistry::iterator it = -           FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); -         it != ie; ++it) { -      if (it->getName() == CI.getFrontendOpts().ActionName) -        return it->instantiate(); -    } - -    CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) -      << CI.getFrontendOpts().ActionName; -    return 0; -  } - -  case PrintDeclContext:       return new DeclContextPrintAction(); -  case PrintPreprocessedInput: return new PrintPreprocessedAction(); -  case RewriteBlocks:          return new RewriteBlocksAction(); -  case RewriteMacros:          return new RewriteMacrosAction(); -  case RewriteObjC:            return new RewriteObjCAction(); -  case RewriteTest:            return new RewriteTestAction(); -  case RunAnalysis:            return new AnalysisAction(); -  case RunPreprocessorOnly:    return new PreprocessOnlyAction(); -  } -} - -static bool ConstructCompilerInvocation(CompilerInvocation &Opts, -                                        Diagnostic &Diags, const char *Argv0) { -  // Initialize target options. -  InitializeTargetOptions(Opts.getTargetOpts()); - -  // Initialize frontend options. -  InitializeFrontendOptions(Opts.getFrontendOpts()); - -  // Determine the input language, we currently require all files to match. -  FrontendOptions::InputKind IK = Opts.getFrontendOpts().Inputs[0].first; -  for (unsigned i = 1, e = Opts.getFrontendOpts().Inputs.size(); i != e; ++i) { -    if (Opts.getFrontendOpts().Inputs[i].first != IK) { -      llvm::errs() << "error: cannot have multiple input files of distinct " -                   << "language kinds without -x\n"; -      return false; -    } -  } - -  // Initialize language options. -  // -  // FIXME: These aren't used during operations on ASTs. Split onto a separate -  // code path to make this obvious. -  if (IK != FrontendOptions::IK_AST) -    InitializeLangOptions(Opts.getLangOpts(), IK); - -  // Initialize the static analyzer options. -  InitializeAnalyzerOptions(Opts.getAnalyzerOpts()); - -  // Initialize the dependency output options (-M...). -  InitializeDependencyOutputOptions(Opts.getDependencyOutputOpts()); - -  // Initialize the header search options. -  InitializeHeaderSearchOptions(Opts.getHeaderSearchOpts(), -                                GetBuiltinIncludePath(Argv0)); - -  // Initialize the other preprocessor options. -  InitializePreprocessorOptions(Opts.getPreprocessorOpts()); - -  // Initialize the preprocessed output options. -  InitializePreprocessorOutputOptions(Opts.getPreprocessorOutputOpts()); - -  // Initialize backend options. -  InitializeCodeGenOptions(Opts.getCodeGenOpts(), Opts.getLangOpts()); - -  return true; -} - -static int cc1_main(Diagnostic &Diags, -                    const char **ArgBegin, const char **ArgEnd, -                    const char *Argv0, void *MainAddr) { -  using namespace clang::driver; - -  llvm::errs() << "cc1 argv:"; -  for (const char **i = ArgBegin; i != ArgEnd; ++i) -    llvm::errs() << " \"" << *i << '"'; -  llvm::errs() << "\n"; - -  // Parse the arguments. -  OptTable *Opts = createCC1OptTable(); -  unsigned MissingArgIndex, MissingArgCount; -  InputArgList *Args = Opts->ParseArgs(ArgBegin, ArgEnd, -                                       MissingArgIndex, MissingArgCount); - -  // Check for missing argument error. -  if (MissingArgCount) -    Diags.Report(clang::diag::err_drv_missing_argument) -      << Args->getArgString(MissingArgIndex) << MissingArgCount; - -  // Dump the parsed arguments. -  llvm::errs() << "cc1 parsed options:\n"; -  for (ArgList::const_iterator it = Args->begin(), ie = Args->end(); -       it != ie; ++it) -    (*it)->dump(); - -  // Create a compiler invocation. -  llvm::errs() << "cc1 creating invocation.\n"; -  CompilerInvocation Invocation; -  CompilerInvocation::CreateFromArgs(Invocation, ArgBegin, ArgEnd, -                                     Argv0, MainAddr, Diags); - -  // Convert the invocation back to argument strings. -  std::vector<std::string> InvocationArgs; -  Invocation.toArgs(InvocationArgs); - -  // Dump the converted arguments. -  llvm::SmallVector<const char*, 32> Invocation2Args; -  llvm::errs() << "invocation argv :"; -  for (unsigned i = 0, e = InvocationArgs.size(); i != e; ++i) { -    Invocation2Args.push_back(InvocationArgs[i].c_str()); -    llvm::errs() << " \"" << InvocationArgs[i] << '"'; -  } -  llvm::errs() << "\n"; - -  // Convert those arguments to another invocation, and check that we got the -  // same thing. -  CompilerInvocation Invocation2; -  CompilerInvocation::CreateFromArgs(Invocation2, Invocation2Args.begin(), -                                     Invocation2Args.end(), Argv0, MainAddr, -                                     Diags); - -  // FIXME: Implement CompilerInvocation comparison. -  if (true) { -    //llvm::errs() << "warning: Invocations differ!\n"; - -    std::vector<std::string> Invocation2Args; -    Invocation2.toArgs(Invocation2Args); -    llvm::errs() << "invocation2 argv:"; -    for (unsigned i = 0, e = Invocation2Args.size(); i != e; ++i) -      llvm::errs() << " \"" << Invocation2Args[i] << '"'; -    llvm::errs() << "\n"; -  } - -  return 0; -} - -int main(int argc, char **argv) { -  llvm::sys::PrintStackTraceOnErrorSignal(); -  llvm::PrettyStackTraceProgram X(argc, argv); -  CompilerInstance Clang(&llvm::getGlobalContext(), false); - -  // Run clang -cc1 test. -  if (argc > 1 && llvm::StringRef(argv[1]) == "-cc1") { -    TextDiagnosticPrinter DiagClient(llvm::errs(), DiagnosticOptions()); -    Diagnostic Diags(&DiagClient); -    return cc1_main(Diags, (const char**) argv + 2, (const char**) argv + argc, -                    argv[0], (void*) (intptr_t) GetBuiltinIncludePath); -  } - -  // Initialize targets first, so that --version shows registered targets. -  llvm::InitializeAllTargets(); -  llvm::InitializeAllAsmPrinters(); - -#if 1 -  llvm::cl::ParseCommandLineOptions(argc, argv, -                              "LLVM 'Clang' Compiler: http://clang.llvm.org\n"); - -  // Construct the diagnostic engine first, so that we can build a diagnostic -  // client to use for any errors during option handling. -  InitializeDiagnosticOptions(Clang.getDiagnosticOpts()); -  Clang.createDiagnostics(argc, argv); -  if (!Clang.hasDiagnostics()) -    return 1; - -  // Set an error handler, so that any LLVM backend diagnostics go through our -  // error handler. -  llvm::llvm_install_error_handler(LLVMErrorHandler, -                                   static_cast<void*>(&Clang.getDiagnostics())); - -  // Now that we have initialized the diagnostics engine, create the target and -  // the compiler invocation object. -  // -  // FIXME: We should move .ast inputs to taking a separate path, they are -  // really quite different. -  if (!ConstructCompilerInvocation(Clang.getInvocation(), -                                   Clang.getDiagnostics(), argv[0])) -    return 1; -#else -  // Buffer diagnostics from argument parsing. -  TextDiagnosticBuffer DiagsBuffer; -  Diagnostic Diags(&DiagsBuffer); - -  CompilerInvocation::CreateFromArgs(Clang.getInvocation(), -                                     (const char**) argv + 1, -                                     (const char**) argv + argc, argv[0], -                                     (void*)(intptr_t) GetBuiltinIncludePath, -                                     Diags); - -  // Create the actual diagnostics engine. -  Clang.createDiagnostics(argc, argv); -  if (!Clang.hasDiagnostics()) -    return 1; - -  // Set an error handler, so that any LLVM backend diagnostics go through our -  // error handler. -  llvm::llvm_install_error_handler(LLVMErrorHandler, -                                   static_cast<void*>(&Clang.getDiagnostics())); - -  DiagsBuffer.FlushDiagnostics(Clang.getDiagnostics()); - -  // If there were any errors in processing arguments, exit now. -  if (Clang.getDiagnostics().getNumErrors()) -    return 1; -#endif - -  // Create the target instance. -  Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(), -                                               Clang.getTargetOpts())); -  if (!Clang.hasTarget()) -    return 1; - -  // Inform the target of the language options -  // -  // FIXME: We shouldn't need to do this, the target should be immutable once -  // created. This complexity should be lifted elsewhere. -  Clang.getTarget().setForcedLangOptions(Clang.getLangOpts()); - -  // Validate/process some options -  if (Clang.getHeaderSearchOpts().Verbose) -    llvm::errs() << "clang-cc version " CLANG_VERSION_STRING -                 << " based upon " << PACKAGE_STRING -                 << " hosted on " << llvm::sys::getHostTriple() << "\n"; - -  if (Clang.getFrontendOpts().ShowTimers) -    Clang.createFrontendTimer(); - -  for (unsigned i = 0, e = Clang.getFrontendOpts().Inputs.size(); i != e; ++i) { -    const std::string &InFile = Clang.getFrontendOpts().Inputs[i].second; - -    // If we aren't using an AST file, setup the file and source managers and -    // the preprocessor. -    bool IsAST = -      Clang.getFrontendOpts().Inputs[i].first == FrontendOptions::IK_AST; -    if (!IsAST) { -      if (!i) { -        // Create a file manager object to provide access to and cache the -        // filesystem. -        Clang.createFileManager(); - -        // Create the source manager. -        Clang.createSourceManager(); -      } else { -        // Reset the ID tables if we are reusing the SourceManager. -        Clang.getSourceManager().clearIDTables(); -      } - -      // Create the preprocessor. -      Clang.createPreprocessor(); -    } - -    llvm::OwningPtr<FrontendAction> Act(CreateFrontendAction(Clang)); -    if (!Act) -      break; - -    if (Act->BeginSourceFile(Clang, InFile, IsAST)) { -      Act->Execute(); -      Act->EndSourceFile(); -    } -  } - -  if (Clang.getDiagnosticOpts().ShowCarets) -    if (unsigned NumDiagnostics = Clang.getDiagnostics().getNumDiagnostics()) -      fprintf(stderr, "%d diagnostic%s generated.\n", NumDiagnostics, -              (NumDiagnostics == 1 ? "" : "s")); - -  if (Clang.getFrontendOpts().ShowStats) { -    Clang.getFileManager().PrintStats(); -    fprintf(stderr, "\n"); -  } - -  // Return the appropriate status when verifying diagnostics. -  // -  // FIXME: If we could make getNumErrors() do the right thing, we wouldn't need -  // this. -  if (Clang.getDiagnosticOpts().VerifyDiagnostics) -    return static_cast<VerifyDiagnosticsClient&>( -      Clang.getDiagnosticClient()).HadErrors(); - -  // Managed static deconstruction. Useful for making things like -  // -time-passes usable. -  llvm::llvm_shutdown(); - -  return (Clang.getDiagnostics().getNumErrors() != 0); -} - diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt index 790021181839..0815554521f0 100644 --- a/tools/driver/CMakeLists.txt +++ b/tools/driver/CMakeLists.txt @@ -2,18 +2,31 @@ set(LLVM_NO_RTTI 1)  set( LLVM_USED_LIBS    clangDriver +  clangFrontend +  clangCodeGen +  clangAnalysis +  clangRewrite +  clangSema +  clangAST +  clangParse +  clangLex    clangBasic    ) -set(LLVM_LINK_COMPONENTS system support bitreader bitwriter) +set( LLVM_LINK_COMPONENTS +  ${LLVM_TARGETS_TO_BUILD} +  bitreader +  bitwriter +  codegen +  ipo +  selectiondag +  )  add_clang_executable(clang    driver.cpp    cc1_main.cpp    ) -add_dependencies(clang clang-cc) -  if(UNIX)    set(CLANGXX_LINK_OR_COPY create_symlink)  else() diff --git a/tools/driver/Makefile b/tools/driver/Makefile index f250651ed7e2..7dab2ac92378 100644 --- a/tools/driver/Makefile +++ b/tools/driver/Makefile @@ -1,10 +1,10 @@  ##===- tools/driver/Makefile -------------------------------*- Makefile -*-===## -#  +#  #                     The LLVM Compiler Infrastructure  #  # This file is distributed under the University of Illinois Open Source  # License. See LICENSE.TXT for details. -#  +#  ##===----------------------------------------------------------------------===##  LEVEL = ../../../.. @@ -13,15 +13,20 @@ TOOLALIAS = clang++  CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include  CXXFLAGS = -fno-rtti -# This tool has no plugins, optimize startup time. +# Clang tool has no plugins, optimize startup time.  TOOL_NO_EXPORTS = 1 -# FIXME: It is unfortunate we need to pull in the bitcode reader and -# writer just to get the serializer stuff used by clangBasic. -LINK_COMPONENTS := system support bitreader bitwriter -USEDLIBS = clangDriver.a clangBasic.a +# Include this here so we can get the configuration of the targets that have +# been configured for construction. We have to do this early so we can set up +# LINK_COMPONENTS before including Makefile.rules +include $(LEVEL)/Makefile.config + +LINK_COMPONENTS := $(TARGETS_TO_BUILD) bitreader bitwriter codegen ipo selectiondag +USEDLIBS = clangFrontend.a clangDriver.a clangCodeGen.a clangAnalysis.a	\ +           clangRewrite.a clangSema.a clangAST.a clangParse.a 		\ +           clangLex.a clangBasic.a -include $(LEVEL)/Makefile.common +include $(LLVM_SRC_ROOT)/Makefile.rules  # Translate make variable to define when building a "production" clang.  ifdef CLANG_IS_PRODUCTION diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp index a9d27efb1c3b..6e82c51d3876 100644 --- a/tools/driver/cc1_main.cpp +++ b/tools/driver/cc1_main.cpp @@ -7,18 +7,331 @@  //  //===----------------------------------------------------------------------===//  // -// This is the entry point to the clang -cc1 functionality. +// This is the entry point to the clang -cc1 functionality, which implements the +// core compiler functionality along with a number of additional tools for +// demonstration and testing purposes.  //  //===----------------------------------------------------------------------===// +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Basic/Version.h" +#include "clang/Driver/Arg.h" +#include "clang/Driver/ArgList.h" +#include "clang/Driver/CC1Options.h" +#include "clang/Driver/DriverDiagnostic.h" +#include "clang/Driver/OptTable.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/CompilerInvocation.h" +#include "clang/Frontend/FrontendActions.h" +#include "clang/Frontend/FrontendDiagnostic.h" +#include "clang/Frontend/FrontendPluginRegistry.h" +#include "clang/Frontend/TextDiagnosticBuffer.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" +#include "clang/Frontend/VerifyDiagnosticsClient.h" +#include "llvm/LLVMContext.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/PrettyStackTrace.h"  #include "llvm/Support/raw_ostream.h" +#include "llvm/System/DynamicLibrary.h" +#include "llvm/System/Host.h" +#include "llvm/System/Path.h" +#include "llvm/System/Signals.h" +#include "llvm/Target/TargetSelect.h" +#include <cstdio> +using namespace clang; + +//===----------------------------------------------------------------------===// +// Main driver +//===----------------------------------------------------------------------===// + +void LLVMErrorHandler(void *UserData, const std::string &Message) { +  Diagnostic &Diags = *static_cast<Diagnostic*>(UserData); + +  Diags.Report(diag::err_fe_error_backend) << Message; + +  // We cannot recover from llvm errors. +  exit(1); +} + +static FrontendAction *CreateFrontendAction(CompilerInstance &CI) { +  using namespace clang::frontend; + +  switch (CI.getFrontendOpts().ProgramAction) { +  default: +    llvm_unreachable("Invalid program action!"); + +  case ASTDump:                return new ASTDumpAction(); +  case ASTPrint:               return new ASTPrintAction(); +  case ASTPrintXML:            return new ASTPrintXMLAction(); +  case ASTView:                return new ASTViewAction(); +  case DumpRawTokens:          return new DumpRawTokensAction(); +  case DumpRecordLayouts:      return new DumpRecordAction(); +  case DumpTokens:             return new DumpTokensAction(); +  case EmitAssembly:           return new EmitAssemblyAction(); +  case EmitBC:                 return new EmitBCAction(); +  case EmitHTML:               return new HTMLPrintAction(); +  case EmitLLVM:               return new EmitLLVMAction(); +  case EmitLLVMOnly:           return new EmitLLVMOnlyAction(); +  case FixIt:                  return new FixItAction(); +  case GeneratePCH:            return new GeneratePCHAction(); +  case GeneratePTH:            return new GeneratePTHAction(); +  case InheritanceView:        return new InheritanceViewAction(); +  case ParseNoop:              return new ParseOnlyAction(); +  case ParsePrintCallbacks:    return new PrintParseAction(); +  case ParseSyntaxOnly:        return new SyntaxOnlyAction(); + +  case PluginAction: { +    if (CI.getFrontendOpts().ActionName == "help") { +      llvm::errs() << "clang -cc1 plugins:\n"; +      for (FrontendPluginRegistry::iterator it = +             FrontendPluginRegistry::begin(), +             ie = FrontendPluginRegistry::end(); +           it != ie; ++it) +        llvm::errs() << "  " << it->getName() << " - " << it->getDesc() << "\n"; +      return 0; +    } + +    for (FrontendPluginRegistry::iterator it = +           FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); +         it != ie; ++it) { +      if (it->getName() == CI.getFrontendOpts().ActionName) +        return it->instantiate(); +    } + +    CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) +      << CI.getFrontendOpts().ActionName; +    return 0; +  } + +  case PrintDeclContext:       return new DeclContextPrintAction(); +  case PrintPreprocessedInput: return new PrintPreprocessedAction(); +  case RewriteBlocks:          return new RewriteBlocksAction(); +  case RewriteMacros:          return new RewriteMacrosAction(); +  case RewriteObjC:            return new RewriteObjCAction(); +  case RewriteTest:            return new RewriteTestAction(); +  case RunAnalysis:            return new AnalysisAction(); +  case RunPreprocessorOnly:    return new PreprocessOnlyAction(); +  } +} + +// FIXME: Define the need for this testing away. +static int cc1_test(Diagnostic &Diags, +                    const char **ArgBegin, const char **ArgEnd) { +  using namespace clang::driver; -int cc1_main(const char **ArgBegin, const char **ArgEnd, -             const char *Argv0, void *MainAddr) {    llvm::errs() << "cc1 argv:";    for (const char **i = ArgBegin; i != ArgEnd; ++i)      llvm::errs() << " \"" << *i << '"';    llvm::errs() << "\n"; +  // Parse the arguments. +  OptTable *Opts = createCC1OptTable(); +  unsigned MissingArgIndex, MissingArgCount; +  InputArgList *Args = Opts->ParseArgs(ArgBegin, ArgEnd, +                                       MissingArgIndex, MissingArgCount); + +  // Check for missing argument error. +  if (MissingArgCount) +    Diags.Report(clang::diag::err_drv_missing_argument) +      << Args->getArgString(MissingArgIndex) << MissingArgCount; + +  // Dump the parsed arguments. +  llvm::errs() << "cc1 parsed options:\n"; +  for (ArgList::const_iterator it = Args->begin(), ie = Args->end(); +       it != ie; ++it) +    (*it)->dump(); + +  // Create a compiler invocation. +  llvm::errs() << "cc1 creating invocation.\n"; +  CompilerInvocation Invocation; +  CompilerInvocation::CreateFromArgs(Invocation, ArgBegin, ArgEnd, Diags); + +  // Convert the invocation back to argument strings. +  std::vector<std::string> InvocationArgs; +  Invocation.toArgs(InvocationArgs); + +  // Dump the converted arguments. +  llvm::SmallVector<const char*, 32> Invocation2Args; +  llvm::errs() << "invocation argv :"; +  for (unsigned i = 0, e = InvocationArgs.size(); i != e; ++i) { +    Invocation2Args.push_back(InvocationArgs[i].c_str()); +    llvm::errs() << " \"" << InvocationArgs[i] << '"'; +  } +  llvm::errs() << "\n"; + +  // Convert those arguments to another invocation, and check that we got the +  // same thing. +  CompilerInvocation Invocation2; +  CompilerInvocation::CreateFromArgs(Invocation2, Invocation2Args.begin(), +                                     Invocation2Args.end(), Diags); + +  // FIXME: Implement CompilerInvocation comparison. +  if (true) { +    //llvm::errs() << "warning: Invocations differ!\n"; + +    std::vector<std::string> Invocation2Args; +    Invocation2.toArgs(Invocation2Args); +    llvm::errs() << "invocation2 argv:"; +    for (unsigned i = 0, e = Invocation2Args.size(); i != e; ++i) +      llvm::errs() << " \"" << Invocation2Args[i] << '"'; +    llvm::errs() << "\n"; +  } +    return 0;  } + +int cc1_main(const char **ArgBegin, const char **ArgEnd, +             const char *Argv0, void *MainAddr) { +  llvm::sys::PrintStackTraceOnErrorSignal(); +  llvm::PrettyStackTraceProgram X(ArgBegin - ArgEnd, ArgBegin); +  CompilerInstance Clang(&llvm::getGlobalContext(), false); + +  // Run clang -cc1 test. +  if (ArgBegin != ArgEnd && llvm::StringRef(ArgBegin[0]) == "-cc1test") { +    TextDiagnosticPrinter DiagClient(llvm::errs(), DiagnosticOptions()); +    Diagnostic Diags(&DiagClient); +    return cc1_test(Diags, ArgBegin + 1, ArgEnd); +  } + +  // Initialize targets first, so that --version shows registered targets. +  llvm::InitializeAllTargets(); +  llvm::InitializeAllAsmPrinters(); + +  // Buffer diagnostics from argument parsing so that we can output them using a +  // well formed diagnostic object. +  TextDiagnosticBuffer DiagsBuffer; +  Diagnostic Diags(&DiagsBuffer); +  CompilerInvocation::CreateFromArgs(Clang.getInvocation(), ArgBegin, ArgEnd, +                                     Diags); + +  // Infer the builtin include path if unspecified. +  if (Clang.getInvocation().getHeaderSearchOpts().UseBuiltinIncludes && +      Clang.getInvocation().getHeaderSearchOpts().ResourceDir.empty()) +    Clang.getInvocation().getHeaderSearchOpts().ResourceDir = +      CompilerInvocation::GetResourcesPath(Argv0, MainAddr); + +  // Honor -help. +  if (Clang.getInvocation().getFrontendOpts().ShowHelp) { +    llvm::OwningPtr<driver::OptTable> Opts(driver::createCC1OptTable()); +    Opts->PrintHelp(llvm::outs(), "clang -cc1", +                    "LLVM 'Clang' Compiler: http://clang.llvm.org"); +    return 0; +  } + +  // Honor -version. +  // +  // FIXME: Use a better -version message? +  if (Clang.getInvocation().getFrontendOpts().ShowVersion) { +    llvm::cl::PrintVersionMessage(); +    return 0; +  } + +  // Create the actual diagnostics engine. +  Clang.createDiagnostics(ArgEnd - ArgBegin, const_cast<char**>(ArgBegin)); +  if (!Clang.hasDiagnostics()) +    return 1; + +  // Set an error handler, so that any LLVM backend diagnostics go through our +  // error handler. +  llvm::llvm_install_error_handler(LLVMErrorHandler, +                                   static_cast<void*>(&Clang.getDiagnostics())); + +  DiagsBuffer.FlushDiagnostics(Clang.getDiagnostics()); + +  // Load any requested plugins. +  for (unsigned i = 0, +         e = Clang.getFrontendOpts().Plugins.size(); i != e; ++i) { +    const std::string &Path = Clang.getFrontendOpts().Plugins[i]; +    std::string Error; +    if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) +      Diags.Report(diag::err_fe_unable_to_load_plugin) << Path << Error; +  } + +  // If there were any errors in processing arguments, exit now. +  if (Clang.getDiagnostics().getNumErrors()) +    return 1; + +  // Create the target instance. +  Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(), +                                               Clang.getTargetOpts())); +  if (!Clang.hasTarget()) +    return 1; + +  // Inform the target of the language options +  // +  // FIXME: We shouldn't need to do this, the target should be immutable once +  // created. This complexity should be lifted elsewhere. +  Clang.getTarget().setForcedLangOptions(Clang.getLangOpts()); + +  // Validate/process some options +  if (Clang.getHeaderSearchOpts().Verbose) +    llvm::errs() << "clang -cc1 version " CLANG_VERSION_STRING +                 << " based upon " << PACKAGE_STRING +                 << " hosted on " << llvm::sys::getHostTriple() << "\n"; + +  if (Clang.getFrontendOpts().ShowTimers) +    Clang.createFrontendTimer(); + +  for (unsigned i = 0, e = Clang.getFrontendOpts().Inputs.size(); i != e; ++i) { +    const std::string &InFile = Clang.getFrontendOpts().Inputs[i].second; + +    // If we aren't using an AST file, setup the file and source managers and +    // the preprocessor. +    bool IsAST = +      Clang.getFrontendOpts().Inputs[i].first == FrontendOptions::IK_AST; +    if (!IsAST) { +      if (!i) { +        // Create a file manager object to provide access to and cache the +        // filesystem. +        Clang.createFileManager(); + +        // Create the source manager. +        Clang.createSourceManager(); +      } else { +        // Reset the ID tables if we are reusing the SourceManager. +        Clang.getSourceManager().clearIDTables(); +      } + +      // Create the preprocessor. +      Clang.createPreprocessor(); +    } + +    llvm::OwningPtr<FrontendAction> Act(CreateFrontendAction(Clang)); +    if (!Act) +      break; + +    if (Act->BeginSourceFile(Clang, InFile, IsAST)) { +      Act->Execute(); +      Act->EndSourceFile(); +    } +  } + +  if (Clang.getDiagnosticOpts().ShowCarets) +    if (unsigned NumDiagnostics = Clang.getDiagnostics().getNumDiagnostics()) +      fprintf(stderr, "%d diagnostic%s generated.\n", NumDiagnostics, +              (NumDiagnostics == 1 ? "" : "s")); + +  if (Clang.getFrontendOpts().ShowStats) { +    Clang.getFileManager().PrintStats(); +    fprintf(stderr, "\n"); +  } + +  // Return the appropriate status when verifying diagnostics. +  // +  // FIXME: If we could make getNumErrors() do the right thing, we wouldn't need +  // this. +  if (Clang.getDiagnosticOpts().VerifyDiagnostics) +    return static_cast<VerifyDiagnosticsClient&>( +      Clang.getDiagnosticClient()).HadErrors(); + +  // Managed static deconstruction. Useful for making things like +  // -time-passes usable. +  llvm::llvm_shutdown(); + +  return (Clang.getDiagnostics().getNumErrors() != 0); +} diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp index c61ee726449f..cfdd9c342acb 100644 --- a/tools/driver/driver.cpp +++ b/tools/driver/driver.cpp @@ -60,7 +60,10 @@ void DriverDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,    OS << '\n';  } -llvm::sys::Path GetExecutablePath(const char *Argv0) { +llvm::sys::Path GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) { +  if (!CanonicalPrefixes) +    return llvm::sys::Path(Argv0); +    // This just needs to be some symbol in the binary; C++ doesn't    // allow taking the address of ::main however.    void *P = (void*) (intptr_t) GetExecutablePath; @@ -190,7 +193,16 @@ int main(int argc, const char **argv) {      return cc1_main(argv+2, argv+argc, argv[0],                      (void*) (intptr_t) GetExecutablePath); -  llvm::sys::Path Path = GetExecutablePath(argv[0]); +  bool CanonicalPrefixes = true; +  for (int i = 1; i < argc; ++i) { +    if (llvm::StringRef(argv[i]) == "-no-canonical-prefixes") { +      CanonicalPrefixes = false; +      break; +    } +  } + +  llvm::sys::Path Path = GetExecutablePath(argv[0], CanonicalPrefixes); +    DriverDiagnosticPrinter DiagClient(Path.getBasename(), llvm::errs());    Diagnostic Diags(&DiagClient); @@ -200,8 +212,8 @@ int main(int argc, const char **argv) {  #else    bool IsProduction = false;  #endif -  Driver TheDriver(Path.getBasename().c_str(), Path.getDirname().c_str(), -                   llvm::sys::getHostTriple().c_str(), +  Driver TheDriver(Path.getBasename(), Path.getDirname(), +                   llvm::sys::getHostTriple(),                     "a.out", IsProduction, Diags);    // Check for ".*++" or ".*++-[^-]*" to determine if we are a C++ @@ -264,4 +276,3 @@ int main(int argc, const char **argv) {    return Res;  } - diff --git a/tools/index-test/CMakeLists.txt b/tools/index-test/CMakeLists.txt index 163afc4ac9f5..9472e580fbc5 100644 --- a/tools/index-test/CMakeLists.txt +++ b/tools/index-test/CMakeLists.txt @@ -3,8 +3,9 @@ set(LLVM_NO_RTTI 1)  set( LLVM_USED_LIBS    clangIndex    clangFrontend -  clangAnalysis +  clangDriver    clangSema +  clangAnalysis    clangAST    clangParse    clangLex @@ -14,6 +15,7 @@ set( LLVM_USED_LIBS  set( LLVM_LINK_COMPONENTS    bitreader    mc +  core    )  add_clang_executable(index-test diff --git a/tools/index-test/Makefile b/tools/index-test/Makefile index 8e7bfe554009..4ee98fc7cc99 100644 --- a/tools/index-test/Makefile +++ b/tools/index-test/Makefile @@ -18,8 +18,8 @@ TOOL_NO_EXPORTS = 1  include $(LEVEL)/Makefile.config -LINK_COMPONENTS := bitreader mc -USEDLIBS = clangIndex.a clangFrontend.a clangDriver.a clangAnalysis.a clangSema.a \ -	   clangAST.a clangParse.a clangLex.a clangBasic.a +LINK_COMPONENTS := bitreader mc core +USEDLIBS = clangIndex.a clangFrontend.a clangDriver.a clangSema.a \ +	   clangAnalysis.a clangAST.a clangParse.a clangLex.a clangBasic.a  include $(LLVM_SRC_ROOT)/Makefile.rules diff --git a/tools/index-test/index-test.cpp b/tools/index-test/index-test.cpp index dd7cbb21642c..ff9fd5431154 100644 --- a/tools/index-test/index-test.cpp +++ b/tools/index-test/index-test.cpp @@ -208,20 +208,26 @@ static void ProcessASTLocation(ASTLocation ASTLoc, Indexer &Idxer) {  static llvm::cl::opt<bool>  ASTFromSource("ast-from-source", -              llvm::cl::desc("Treat the inputs as source files to parse.")); +              llvm::cl::desc("Treat the inputs as source files to parse")); + +static llvm::cl::list<std::string> +CompilerArgs("arg", llvm::cl::desc("Extra arguments to use during parsing"));  static llvm::cl::list<std::string>  InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input AST files>")); -void CreateCompilerInvocation(const std::string &Filename, -                              CompilerInvocation &CI, Diagnostic &Diags, -                              const char *argv0) { +ASTUnit *CreateFromSource(const std::string &Filename, Diagnostic &Diags, +                          const char *Argv0) {    llvm::SmallVector<const char *, 16> Args;    Args.push_back(Filename.c_str()); - -  void *MainAddr = (void*) (intptr_t) CreateCompilerInvocation; -  CompilerInvocation::CreateFromArgs(CI, Args.data(), Args.data() + Args.size(), -                                     argv0, MainAddr, Diags); +  for (unsigned i = 0, e = CompilerArgs.size(); i != e; ++i) +    Args.push_back(CompilerArgs[i].c_str()); + +  void *MainAddr = (void*) (intptr_t) CreateFromSource; +  std::string ResourceDir = +    CompilerInvocation::GetResourcesPath(Argv0, MainAddr); +  return ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(), +                                      Diags, ResourceDir);  }  int main(int argc, char **argv) { @@ -234,9 +240,9 @@ int main(int argc, char **argv) {    Indexer Idxer(Prog);    llvm::SmallVector<TUnit*, 4> TUnits; -  TextDiagnosticPrinter DiagClient(llvm::errs(), DiagnosticOptions(), false); +  DiagnosticOptions DiagOpts;    llvm::OwningPtr<Diagnostic> Diags( -    CompilerInstance::createDiagnostics(DiagnosticOptions(), argc, argv)); +    CompilerInstance::createDiagnostics(DiagOpts, argc, argv));    // If no input was specified, read from stdin.    if (InputFilenames.empty()) @@ -244,23 +250,13 @@ int main(int argc, char **argv) {    for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {      const std::string &InFile = InputFilenames[i]; - -    std::string ErrMsg;      llvm::OwningPtr<ASTUnit> AST; - -    if (ASTFromSource) { -      CompilerInvocation CI; -      CreateCompilerInvocation(InFile, CI, *Diags, argv[0]); -      AST.reset(ASTUnit::LoadFromCompilerInvocation(CI, *Diags)); -      if (!AST) -        ErrMsg = "unable to create AST"; -    } else -      AST.reset(ASTUnit::LoadFromPCHFile(InFile, &ErrMsg)); - -    if (!AST) { -      llvm::errs() << "[" << InFile << "] Error: " << ErrMsg << '\n'; +    if (ASTFromSource) +      AST.reset(CreateFromSource(InFile, *Diags, argv[0])); +    else +      AST.reset(ASTUnit::LoadFromPCHFile(InFile, *Diags)); +    if (!AST)        return 1; -    }      TUnit *TU = new TUnit(AST.take(), InFile);      TUnits.push_back(TU); diff --git a/tools/scan-build/ccc-analyzer b/tools/scan-build/ccc-analyzer index 25b980057408..aca411f67ae8 100755 --- a/tools/scan-build/ccc-analyzer +++ b/tools/scan-build/ccc-analyzer @@ -14,14 +14,38 @@  use strict;  use warnings; +use FindBin;  use Cwd qw/ getcwd abs_path /;  use File::Temp qw/ tempfile /;  use File::Path qw / mkpath /;  use File::Basename;  use Text::ParseWords; -my $CC = $ENV{'CCC_CC'}; -if (!defined $CC) { $CC = "gcc"; } +##===----------------------------------------------------------------------===## +# Compiler command setup. +##===----------------------------------------------------------------------===## + +my $Compiler; +my $Clang; + +if ($FindBin::Script =~ /c\+\+-analyzer/) { +  $Compiler = $ENV{'CCC_CXX'}; +  if (!defined $Compiler) { $Compiler = "g++"; } +   +  $Clang = $ENV{'CLANG_CXX'}; +  if (!defined $Clang) { $Clang = 'clang++'; } +} +else { +  $Compiler = $ENV{'CCC_CC'}; +  if (!defined $Compiler) { $Compiler = "gcc"; } + +  $Clang = $ENV{'CLANG'}; +  if (!defined $Clang) { $Clang = 'clang'; } +} + +##===----------------------------------------------------------------------===## +# Cleanup. +##===----------------------------------------------------------------------===##  my $ReportFailures = $ENV{'CCC_REPORT_FAILURES'};  if (!defined $ReportFailures) { $ReportFailures = 1; } @@ -53,7 +77,7 @@ my $ParserRejects = "Parser Rejects";  my $AttributeIgnored = "Attribute Ignored";  sub ProcessClangFailure { -  my ($ClangCC, $Lang, $file, $Args, $HtmlDir, $ErrorType, $ofile) = @_; +  my ($Clang, $Lang, $file, $Args, $HtmlDir, $ErrorType, $ofile) = @_;    my $Dir = "$HtmlDir/failures";    mkpath $Dir; @@ -69,7 +93,7 @@ sub ProcessClangFailure {    my ($PPH, $PPFile) = tempfile( $prefix . "_XXXXXX",                                   SUFFIX => GetPPExt($Lang),                                   DIR => $Dir); -  system $ClangCC, @$Args, "-E", "-o", $PPFile; +  system $Clang, @$Args, "-E", "-o", $PPFile;    close ($PPH);    # Create the info file. @@ -79,7 +103,7 @@ sub ProcessClangFailure {    print OUT "@$Args\n";    close OUT;    `uname -a >> $PPFile.info.txt 2>&1`; -  `$CC -v >> $PPFile.info.txt 2>&1`; +  `$Compiler -v >> $PPFile.info.txt 2>&1`;    system 'mv',$ofile,"$PPFile.stderr.txt";    return (basename $PPFile);  } @@ -88,10 +112,6 @@ sub ProcessClangFailure {  #  Running the analyzer.  ##----------------------------------------------------------------------------## -# Determine what clang executable to use. -my $Clang = $ENV{'CLANG'}; -if (!defined $Clang) { $Clang = 'clang'; } -  sub GetCCArgs {    my $Args = shift; @@ -106,14 +126,14 @@ sub GetCCArgs {    close(TO_PARENT);    my $line;    while (<FROM_CHILD>) { -    next if (!/clang-cc/); +    next if (!/-cc1/);      $line = $_;    }    waitpid($pid,0);    close(FROM_CHILD); -  die "could not find clang-cc line\n" if (!defined $line); +  die "could not find clang line\n" if (!defined $line);    # Strip the newline and initial whitspace    chomp $line;      $line =~ s/^\s+//; @@ -124,19 +144,16 @@ sub GetCCArgs {      $items[$i] =~ s/\"$//;    }    my $cmd = shift @items; -  die "cannot find 'clang-cc' in 'clang' command\n" if (!($cmd =~ /clang-cc/)); +  die "cannot find 'clang' in 'clang' command\n" if (!($cmd =~ /clang/));    return \@items;  }  sub Analyze { -  my ($ClangCC, $Args, $AnalyzeArgs, $Lang, $Output, $Verbose, $HtmlDir, +  my ($Clang, $Args, $AnalyzeArgs, $Lang, $Output, $Verbose, $HtmlDir,        $file, $Analyses) = @_;    $Args = GetCCArgs($Args); -  # Skip anything related to C++. -  return if ($Lang =~ /c[+][+]/); -    my $RunAnalyzer = 0;    my $Cmd;    my @CmdArgs; @@ -152,13 +169,15 @@ sub Analyze {      @CmdArgsSansAnalyses = @CmdArgs;        }    else { -    $Cmd = $ClangCC; +    $Cmd = $Clang; +    push @CmdArgs, "-cc1";      push @CmdArgs,'-DIBOutlet=__attribute__((iboutlet))'; -    push @CmdArgs,@$Args; +    push @CmdArgs, @$Args;      @CmdArgsSansAnalyses = @CmdArgs;      push @CmdArgs,'-analyze';      push @CmdArgs,"-analyzer-display-progress";      push @CmdArgs,"-analyzer-eagerly-assume"; +    push @CmdArgs,"-analyzer-opt-analyze-nested-blocks";      push @CmdArgs,(split /\s/,$Analyses);      if (defined $ENV{"CCC_EXPERIMENTAL_CHECKS"}) { @@ -236,13 +255,13 @@ sub Analyze {    # Did the command die because of a signal?    if ($ReportFailures) { -    if ($Result & 127 and $Cmd eq $ClangCC and defined $HtmlDir) { -      ProcessClangFailure($ClangCC, $Lang, $file, \@CmdArgsSansAnalyses, +    if ($Result & 127 and $Cmd eq $Clang and defined $HtmlDir) { +      ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses,                            $HtmlDir, "Crash", $ofile);      }      elsif ($Result) {        if ($IncludeParserRejects && !($file =~/conftest/)) { -        ProcessClangFailure($ClangCC, $Lang, $file, \@CmdArgsSansAnalyses, +        ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses,                              $HtmlDir, $ParserRejects, $ofile);        }      } @@ -274,7 +293,7 @@ sub Analyze {            # Add this file to the list of files that contained this attribute.            # Generate a preprocessed file if we haven't already.            if (!(defined $ppfile)) { -            $ppfile = ProcessClangFailure($ClangCC, $Lang, $file, +            $ppfile = ProcessClangFailure($Clang, $Lang, $file,                                            \@CmdArgsSansAnalyses,                                            $HtmlDir, $AttributeIgnored, $ofile);            } @@ -359,7 +378,9 @@ my %UniqueOptions = (  my %LangsAccepted = (    "objective-c" => 1, -  "c" => 1 +  "c" => 1, +  "c++" => 1, +  "objective-c++" => 1  );  ##----------------------------------------------------------------------------## @@ -375,7 +396,7 @@ my $Output;  my %Uniqued;  # Forward arguments to gcc. -my $Status = system($CC,@ARGV); +my $Status = system($Compiler,@ARGV);  if ($Status) { exit($Status >> 8); }  # Get the analysis options. @@ -399,10 +420,6 @@ my $Verbose = 0;  if (defined $ENV{CCC_ANALYZER_VERBOSE}) { $Verbose = 1; }  if (defined $ENV{CCC_ANALYZER_LOG}) { $Verbose = 2; } -# Determine what clang-cc executable to use. -my $ClangCC = $ENV{'CLANG_CC'}; -if (!defined $ClangCC) { $ClangCC = 'clang-cc'; } -  # Get the HTML output directory.  my $HtmlDir = $ENV{'CCC_ANALYZER_HTML'}; @@ -617,12 +634,12 @@ if ($Action eq 'compile' or $Action eq 'link') {          push @NewArgs, '-arch';          push @NewArgs, $arch;          push @NewArgs, @CmdArgs; -        Analyze($ClangCC, \@NewArgs, \@AnalyzeArgs, $FileLang, $Output, +        Analyze($Clang, \@NewArgs, \@AnalyzeArgs, $FileLang, $Output,                  $Verbose, $HtmlDir, $file, $Analyses);        }      }      else { -      Analyze($ClangCC, \@CmdArgs, \@AnalyzeArgs, $FileLang, $Output, +      Analyze($Clang, \@CmdArgs, \@AnalyzeArgs, $FileLang, $Output,                $Verbose, $HtmlDir, $file, $Analyses);      }    } diff --git a/tools/scan-build/scan-build b/tools/scan-build/scan-build index 8d99f070eae9..f978a888be83 100755 --- a/tools/scan-build/scan-build +++ b/tools/scan-build/scan-build @@ -26,7 +26,6 @@ my $Verbose = 0;       # Verbose output from this script.  my $Prog = "scan-build";  my $BuildName;  my $BuildDate; -my $CXX;  # Leave undefined initially.  my $TERM = $ENV{'TERM'};  my $UseColor = (defined $TERM and $TERM eq 'xterm-color' and -t STDOUT @@ -81,43 +80,26 @@ sub DieDiag {  # Some initial preprocessing of Clang options.  ##----------------------------------------------------------------------------## -# First, look for 'clang-cc' in libexec. -my $ClangCCSB = Cwd::realpath("$RealBin/libexec/clang-cc"); -# Second, look for 'clang-cc' in the same directory as scan-build. -if (!defined $ClangCCSB || ! -x $ClangCCSB) { -  $ClangCCSB = Cwd::realpath("$RealBin/clang-cc"); -} -# Third, look for 'clang-cc' in ../libexec -if (!defined $ClangCCSB || ! -x $ClangCCSB) { -  $ClangCCSB = Cwd::realpath("$RealBin/../libexec/clang-cc"); -} -# Finally, default to looking for 'clang-cc' in the path. -if (!defined $ClangCCSB || ! -x $ClangCCSB) { -  $ClangCCSB = "clang-cc"; -} -my $ClangCC = $ClangCCSB; - -# Now find 'clang' +# Find 'clang'  my $ClangSB = Cwd::realpath("$RealBin/bin/clang"); +my $ClangCXXSB;  if (!defined $ClangSB || ! -x $ClangSB) {    $ClangSB = Cwd::realpath("$RealBin/clang"); -} -# Third, look for 'clang' in ../bin -if (!defined $ClangSB || ! -x $ClangSB) { -  $ClangSB = Cwd::realpath("$RealBin/../bin/clang"); -} -# Finally, default to looking for 'clang-cc' in the path. -if (!defined $ClangSB || ! -x $ClangSB) { -  $ClangSB = "clang"; +  if (defined $ClangSB) { $ClangCXXSB = $ClangSB . "++"; }  }  my $Clang = $ClangSB; - +my $ClangCXX = $ClangCXXSB; +# Default to looking for 'clang' in the path. +if (!defined $Clang || ! -x $Clang) { +  $Clang = "clang"; +  $ClangCXX = "clang++"; +}  my %AvailableAnalyses;  # Query clang for analysis options. -open(PIPE, "-|", $ClangCC, "--help") or -  DieDiag("Cannot execute '$ClangCC'\n"); +open(PIPE, "-|", $Clang, "-cc1", "--help") or +  DieDiag("Cannot execute '$Clang'\n");  my $FoundAnalysis = 0; @@ -128,17 +110,14 @@ while(<PIPE>) {      }      next;    } -        if (/^\s\s\s\s([^\s]+)\s(.+)$/) {      next if ($1 =~ /-dump/ or $1 =~ /-view/  -             or $1 =~ /-warn-uninit/); -              +             or $1 =~ /-warn-uninit/);                   $AvailableAnalyses{$1} = $2;      next;    }      last;  } -  close (PIPE);  my %AnalysesDefaultEnabled = ( @@ -156,10 +135,8 @@ my %AnalysesDefaultEnabled = (  ##----------------------------------------------------------------------------##  sub GetHTMLRunDir {   -    die "Not enough arguments." if (@_ == 0);   -  my $Dir = shift @_; -     +  my $Dir = shift @_;        my $TmpMode = 0;    if (!defined $Dir) {      if (`uname` =~ /Darwin/) { @@ -168,8 +145,7 @@ sub GetHTMLRunDir {      }      else {        $Dir = "/tmp"; -    } -     +    }          $TmpMode = 1;    } @@ -177,42 +153,32 @@ sub GetHTMLRunDir {    while ($Dir =~ /\/$/) { chop $Dir; }    # Get current date and time. -   -  my @CurrentTime = localtime(); -   +  my @CurrentTime = localtime();      my $year  = $CurrentTime[5] + 1900;    my $day   = $CurrentTime[3];    my $month = $CurrentTime[4] + 1; -      my $DateString = sprintf("%d-%02d-%02d", $year, $month, $day); -  # Determine the run number. -   +  # Determine the run number.      my $RunNumber; -  if (-d $Dir) { -     +  if (-d $Dir) {          if (! -r $Dir) {        DieDiag("directory '$Dir' exists but is not readable.\n"); -    } -     -    # Iterate over all files in the specified directory. -     -    my $max = 0; -     +    }     +    # Iterate over all files in the specified directory.     +    my $max = 0;          opendir(DIR, $Dir);      my @FILES = grep { -d "$Dir/$_" } readdir(DIR);      closedir(DIR); -     -    foreach my $f (@FILES) { +    foreach my $f (@FILES) {        # Strip the prefix '$Prog-' if we are dumping files to /tmp.        if ($TmpMode) {          next if (!($f =~ /^$Prog-(.+)/));          $f = $1;        } -              my @x = split/-/, $f;        next if (scalar(@x) != 4);        next if ($x[0] != $year); @@ -836,14 +802,26 @@ sub RunBuildCommand {        $Cmd =~ /(.*\/?ccc-analyzer[^\/]*$)/) {      if (!($Cmd =~ /ccc-analyzer/) and !defined $ENV{"CCC_CC"}) { -      $ENV{"CCC_CC"} = $1; +      $ENV{"CCC_CC"} = $1;            }      shift @$Args;      unshift @$Args, $CCAnalyzer;    } +  elsif ($Cmd =~ /(.*\/?g\+\+[^\/]*$)/ or  +        $Cmd =~ /(.*\/?c\+\+[^\/]*$)/ or +        $Cmd =~ /(.*\/?llvm-g\+\+[^\/]*$)/ or +        $Cmd =~ /(.*\/?c\+\+-analyzer[^\/]*$)/) { +    if (!($Cmd =~ /c\+\+-analyzer/) and !defined $ENV{"CCC_CXX"}) { +      $ENV{"CCC_CXX"} = $1;       +    }         +    shift @$Args; +    unshift @$Args, $CCAnalyzer; +  }    elsif ($IgnoreErrors) {      if ($Cmd eq "make" or $Cmd eq "gmake") { +      AddIfNotPresent($Args, "CC=$CCAnalyzer"); +      AddIfNotPresent($Args, "CXX=$CCAnalyzer");        AddIfNotPresent($Args,"-k");        AddIfNotPresent($Args,"-i");      } @@ -860,6 +838,7 @@ sub RunBuildCommand {          if ($Args->[$i] eq "-sdk" && $i + 1 < scalar(@$Args)) {            if (@$Args[$i+1] =~ /^iphonesimulator3/) {              $ENV{"CCC_CC"} = "gcc-4.2"; +            $ENV{"CCC_CXX"} = "g++-4.2";                        }          }        } @@ -874,10 +853,10 @@ sub RunBuildCommand {      # When 'CC' is set, xcodebuild uses it to do all linking, even if we are      # linking C++ object files.  Set 'LDPLUSPLUS' so that xcodebuild uses 'g++'      # when linking such files. -    die if (!defined $CXX); -    my $LDPLUSPLUS = `which $CXX`; -    $LDPLUSPLUS =~ s/\015?\012//;  # strip newlines -    $ENV{'LDPLUSPLUS'} = $LDPLUSPLUS;     +    if (!defined $ENV{'CCC_CXX'}) { +      $ENV{'CCC_CXX'} = 'g++';       +    } +    $ENV{'LDPLUSPLUS'} = $ENV{'CCC_CXX'};    }    return (system(@$Args) >> 8); @@ -1125,16 +1104,19 @@ while (@ARGV) {    if ($arg =~ /^--use-c\+\+(=(.+))?$/) {      shift @ARGV; +    my $cxx;          if (!defined $2 || $2 eq "") {        if (!@ARGV) {          DieDiag("'--use-c++' option requires a compiler executable name.\n");        } -      $CXX = shift @ARGV; +      $cxx = shift @ARGV;      }      else { -      $CXX = $2; +      $cxx = $2;      } +     +    $ENV{"CCC_CXX"} = $cxx;      next;    } @@ -1206,32 +1188,28 @@ $HtmlDir = GetHTMLRunDir($HtmlDir);  # Set the appropriate environment variables.  SetHtmlEnv(\@ARGV, $HtmlDir); -my $Cmd = Cwd::realpath("$RealBin/libexec/ccc-analyzer"); +my $AbsRealBin = Cwd::realpath($RealBin); +my $Cmd = "$AbsRealBin/libexec/ccc-analyzer"; +my $CmdCXX = "$AbsRealBin/libexec/c++-analyzer"; +  if (!defined $Cmd || ! -x $Cmd) { -  $Cmd = Cwd::realpath("$RealBin/ccc-analyzer"); +  $Cmd = "$AbsRealBin/ccc-analyzer";    DieDiag("Executable 'ccc-analyzer' does not exist at '$Cmd'\n") if(! -x $Cmd);  } - -if (!defined $ClangCCSB || ! -x $ClangCCSB) { -  Diag("'clang-cc' executable not found in '$RealBin/libexec'.\n"); -  Diag("Using 'clang-cc' from path.\n"); +if (!defined $CmdCXX || ! -x $CmdCXX) { +  $CmdCXX = "$AbsRealBin/c++-analyzer"; +  DieDiag("Executable 'c++-analyzer' does not exist at '$CmdCXX'\n") if(! -x $CmdCXX);  } +  if (!defined $ClangSB || ! -x $ClangSB) {    Diag("'clang' executable not found in '$RealBin/bin'.\n");    Diag("Using 'clang' from path.\n");  } -if (defined $CXX) { -  $ENV{'CXX'} = $CXX; -} -else { -  $CXX = 'g++';  # This variable is used by other parts of scan-build -                 # that need to know a default C++ compiler to fall back to. -} -    $ENV{'CC'} = $Cmd; -$ENV{'CLANG_CC'} = $ClangCC; +$ENV{'CXX'} = $CmdCXX;  $ENV{'CLANG'} = $Clang; +$ENV{'CLANG_CXX'} = $ClangCXX;  if ($Verbose >= 2) {    $ENV{'CCC_ANALYZER_VERBOSE'} = 1;  | 
