示例#1
0
TEST(Option, SlurpJoinedEmpty) {
  TestOptTable T;
  unsigned MAI, MAC;

  const char *MyArgs[] = { "-A", "-slurpjoined" };
  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
  EXPECT_TRUE(AL.hasArg(OPT_A));
  EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));
  EXPECT_EQ(AL.getAllArgValues(OPT_SlurpJoined).size(), 0U);
}
示例#2
0
TEST(Option, SlurpJoinedButSeparate) {
  TestOptTable T;
  unsigned MAI, MAC;

  const char *MyArgs[] = { "-A", "-slurpjoined", "foo", "bar", "baz" };
  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
  EXPECT_TRUE(AL.hasArg(OPT_A));
  EXPECT_TRUE(AL.hasArg(OPT_SlurpJoined));
  EXPECT_EQ(3U, AL.getAllArgValues(OPT_SlurpJoined).size());
  EXPECT_EQ("foo", AL.getAllArgValues(OPT_SlurpJoined)[0]);
  EXPECT_EQ("bar", AL.getAllArgValues(OPT_SlurpJoined)[1]);
  EXPECT_EQ("baz", AL.getAllArgValues(OPT_SlurpJoined)[2]);
}
示例#3
0
TEST(Option, Slurp) {
  TestOptTable T;
  unsigned MAI, MAC;

  const char *MyArgs[] = { "-A", "-slurp", "-B", "--", "foo" };
  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
  EXPECT_EQ(AL.size(), 2U);
  EXPECT_TRUE(AL.hasArg(OPT_A));
  EXPECT_FALSE(AL.hasArg(OPT_B));
  EXPECT_TRUE(AL.hasArg(OPT_Slurp));
  EXPECT_EQ(3U, AL.getAllArgValues(OPT_Slurp).size());
  EXPECT_EQ("-B", AL.getAllArgValues(OPT_Slurp)[0]);
  EXPECT_EQ("--", AL.getAllArgValues(OPT_Slurp)[1]);
  EXPECT_EQ("foo", AL.getAllArgValues(OPT_Slurp)[2]);
}
示例#4
0
TEST(Option, OptionParsing) {
  TestOptTable T;
  unsigned MAI, MAC;
  InputArgList AL = T.ParseArgs(Args, MAI, MAC);

  // Check they all exist.
  EXPECT_TRUE(AL.hasArg(OPT_A));
  EXPECT_TRUE(AL.hasArg(OPT_B));
  EXPECT_TRUE(AL.hasArg(OPT_C));
  EXPECT_TRUE(AL.hasArg(OPT_D));
  EXPECT_TRUE(AL.hasArg(OPT_E));
  EXPECT_TRUE(AL.hasArg(OPT_F));
  EXPECT_TRUE(AL.hasArg(OPT_G));

  // Check the values.
  EXPECT_EQ("hi", AL.getLastArgValue(OPT_B));
  EXPECT_EQ("bye", AL.getLastArgValue(OPT_C));
  EXPECT_EQ("adena", AL.getLastArgValue(OPT_D));
  std::vector<std::string> Es = AL.getAllArgValues(OPT_E);
  EXPECT_EQ("apple", Es[0]);
  EXPECT_EQ("bloom", Es[1]);
  EXPECT_EQ("42", AL.getLastArgValue(OPT_F));
  std::vector<std::string> Gs = AL.getAllArgValues(OPT_G);
  EXPECT_EQ("chuu", Gs[0]);
  EXPECT_EQ("2", Gs[1]);

  // Check the help text.
  std::string Help;
  raw_string_ostream RSO(Help);
  T.PrintHelp(RSO, "test", "title!");
  EXPECT_NE(std::string::npos, Help.find("-A"));

  // Check usage line.
  T.PrintHelp(RSO, "name [options] file...", "title!");
  EXPECT_NE(std::string::npos, Help.find("USAGE: name [options] file...\n"));

  // Test aliases.
  auto Cs = AL.filtered(OPT_C);
  ASSERT_NE(Cs.begin(), Cs.end());
  EXPECT_EQ("desu", StringRef((*Cs.begin())->getValue()));
  ArgStringList ASL;
  (*Cs.begin())->render(AL, ASL);
  ASSERT_EQ(2u, ASL.size());
  EXPECT_EQ("-C", StringRef(ASL[0]));
  EXPECT_EQ("desu", StringRef(ASL[1]));
}
示例#5
0
TEST(Option, ParseAliasInGroup) {
  TestOptTable T;
  unsigned MAI, MAC;

  const char *MyArgs[] = { "-I" };
  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
  EXPECT_TRUE(AL.hasArg(OPT_H));
}
示例#6
0
TEST(Option, ParseWithFlagExclusions) {
  TestOptTable T;
  unsigned MAI, MAC;

  // Exclude flag3 to avoid parsing as OPT_SLASH_C.
  InputArgList AL = T.ParseArgs(Args, MAI, MAC,
                                /*FlagsToInclude=*/0,
                                /*FlagsToExclude=*/OptFlag3);
  EXPECT_TRUE(AL.hasArg(OPT_A));
  EXPECT_TRUE(AL.hasArg(OPT_C));
  EXPECT_FALSE(AL.hasArg(OPT_SLASH_C));

  // Exclude flag1 to avoid parsing as OPT_C.
  AL = T.ParseArgs(Args, MAI, MAC,
                   /*FlagsToInclude=*/0,
                   /*FlagsToExclude=*/OptFlag1);
  EXPECT_TRUE(AL.hasArg(OPT_B));
  EXPECT_FALSE(AL.hasArg(OPT_C));
  EXPECT_TRUE(AL.hasArg(OPT_SLASH_C));

  const char *NewArgs[] = { "/C", "foo", "--C=bar" };
  AL = T.ParseArgs(NewArgs, MAI, MAC);
  EXPECT_TRUE(AL.hasArg(OPT_SLASH_C));
  EXPECT_TRUE(AL.hasArg(OPT_C));
  EXPECT_EQ("foo", AL.getLastArgValue(OPT_SLASH_C));
  EXPECT_EQ("bar", AL.getLastArgValue(OPT_C));
}
示例#7
0
TEST(Option, DoNotIgnoreCase) {
  TestOptTable T;
  unsigned MAI, MAC;

  const char *MyArgs[] = { "-a", "-joo" };
  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
  EXPECT_FALSE(AL.hasArg(OPT_A));
  EXPECT_FALSE(AL.hasArg(OPT_B));
}
示例#8
0
TEST(Option, AliasArgs) {
  TestOptTable T;
  unsigned MAI, MAC;

  const char *MyArgs[] = { "-J", "-Joo" };
  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
  EXPECT_TRUE(AL.hasArg(OPT_B));
  EXPECT_EQ("foo", AL.getAllArgValues(OPT_B)[0]);
  EXPECT_EQ("bar", AL.getAllArgValues(OPT_B)[1]);
}
示例#9
0
TEST(Option, FlagAliasToJoined) {
  TestOptTable T;
  unsigned MAI, MAC;

  // Check that a flag alias provides an empty argument to a joined option.
  const char *MyArgs[] = { "-K" };
  InputArgList AL = T.ParseArgs(MyArgs, MAI, MAC);
  EXPECT_EQ(AL.size(), 1U);
  EXPECT_TRUE(AL.hasArg(OPT_B));
  EXPECT_EQ(1U, AL.getAllArgValues(OPT_B).size());
  EXPECT_EQ("", AL.getAllArgValues(OPT_B)[0]);
}
示例#10
0
bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
                                         ArrayRef<const char *> Argv,
                                         DiagnosticsEngine &Diags) {
  bool Success = true;

  // Parse the arguments.
  std::unique_ptr<OptTable> OptTbl(createDriverOptTable());

  const unsigned IncludedFlagsBitmask = options::CC1AsOption;
  unsigned MissingArgIndex, MissingArgCount;
  InputArgList Args = OptTbl->ParseArgs(Argv, MissingArgIndex, MissingArgCount,
                                        IncludedFlagsBitmask);

  // Check for missing argument error.
  if (MissingArgCount) {
    Diags.Report(diag::err_drv_missing_argument)
        << Args.getArgString(MissingArgIndex) << MissingArgCount;
    Success = false;
  }

  // Issue errors on unknown arguments.
  for (const Arg *A : Args.filtered(OPT_UNKNOWN)) {
    auto ArgString = A->getAsString(Args);
    std::string Nearest;
    if (OptTbl->findNearest(ArgString, Nearest, IncludedFlagsBitmask) > 1)
      Diags.Report(diag::err_drv_unknown_argument) << ArgString;
    else
      Diags.Report(diag::err_drv_unknown_argument_with_suggestion)
          << ArgString << Nearest;
    Success = false;
  }

  // Construct the invocation.

  // Target Options
  Opts.Triple = llvm::Triple::normalize(Args.getLastArgValue(OPT_triple));
  Opts.CPU = Args.getLastArgValue(OPT_target_cpu);
  Opts.Features = Args.getAllArgValues(OPT_target_feature);

  // Use the default target triple if unspecified.
  if (Opts.Triple.empty())
    Opts.Triple = llvm::sys::getDefaultTargetTriple();

  // Language Options
  Opts.IncludePaths = Args.getAllArgValues(OPT_I);
  Opts.NoInitialTextSection = Args.hasArg(OPT_n);
  Opts.SaveTemporaryLabels = Args.hasArg(OPT_msave_temp_labels);
  // Any DebugInfoKind implies GenDwarfForAssembly.
  Opts.GenDwarfForAssembly = Args.hasArg(OPT_debug_info_kind_EQ);

  if (const Arg *A = Args.getLastArg(OPT_compress_debug_sections,
                                     OPT_compress_debug_sections_EQ)) {
    if (A->getOption().getID() == OPT_compress_debug_sections) {
      // TODO: be more clever about the compression type auto-detection
      Opts.CompressDebugSections = llvm::DebugCompressionType::GNU;
    } else {
      Opts.CompressDebugSections =
          llvm::StringSwitch<llvm::DebugCompressionType>(A->getValue())
              .Case("none", llvm::DebugCompressionType::None)
              .Case("zlib", llvm::DebugCompressionType::Z)
              .Case("zlib-gnu", llvm::DebugCompressionType::GNU)
              .Default(llvm::DebugCompressionType::None);
    }
  }

  Opts.RelaxELFRelocations = Args.hasArg(OPT_mrelax_relocations);
  Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 2, Diags);
  Opts.DwarfDebugFlags = Args.getLastArgValue(OPT_dwarf_debug_flags);
  Opts.DwarfDebugProducer = Args.getLastArgValue(OPT_dwarf_debug_producer);
  Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir);
  Opts.MainFileName = Args.getLastArgValue(OPT_main_file_name);

  for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ))
    Opts.DebugPrefixMap.insert(StringRef(Arg).split('='));

  // Frontend Options
  if (Args.hasArg(OPT_INPUT)) {
    bool First = true;
    for (const Arg *A : Args.filtered(OPT_INPUT)) {
      if (First) {
        Opts.InputFile = A->getValue();
        First = false;
      } else {
        Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(Args);
        Success = false;
      }
    }
  }
  Opts.LLVMArgs = Args.getAllArgValues(OPT_mllvm);
  Opts.OutputPath = Args.getLastArgValue(OPT_o);
  Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file);
  if (Arg *A = Args.getLastArg(OPT_filetype)) {
    StringRef Name = A->getValue();
    unsigned OutputType = StringSwitch<unsigned>(Name)
      .Case("asm", FT_Asm)
      .Case("null", FT_Null)
      .Case("obj", FT_Obj)
      .Default(~0U);
    if (OutputType == ~0U) {
      Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
      Success = false;
    } else
      Opts.OutputType = FileType(OutputType);
  }
  Opts.ShowHelp = Args.hasArg(OPT_help);
  Opts.ShowVersion = Args.hasArg(OPT_version);

  // Transliterate Options
  Opts.OutputAsmVariant =
      getLastArgIntValue(Args, OPT_output_asm_variant, 0, Diags);
  Opts.ShowEncoding = Args.hasArg(OPT_show_encoding);
  Opts.ShowInst = Args.hasArg(OPT_show_inst);

  // Assemble Options
  Opts.RelaxAll = Args.hasArg(OPT_mrelax_all);
  Opts.NoExecStack = Args.hasArg(OPT_mno_exec_stack);
  Opts.FatalWarnings = Args.hasArg(OPT_massembler_fatal_warnings);
  Opts.RelocationModel = Args.getLastArgValue(OPT_mrelocation_model, "pic");
  Opts.IncrementalLinkerCompatible =
      Args.hasArg(OPT_mincremental_linker_compatible);
  Opts.SymbolDefs = Args.getAllArgValues(OPT_defsym);

  // EmbedBitcode Option. If -fembed-bitcode is enabled, set the flag.
  // EmbedBitcode behaves the same for all embed options for assembly files.
  if (auto *A = Args.getLastArg(OPT_fembed_bitcode_EQ)) {
    Opts.EmbedBitcode = llvm::StringSwitch<unsigned>(A->getValue())
                            .Case("all", 1)
                            .Case("bitcode", 1)
                            .Case("marker", 1)
                            .Default(0);
  }

  return Success;
}
Compilation *Driver::BuildCompilation(int argc, const char **argv) {
    llvm::PrettyStackTraceString CrashInfo("Compilation construction");

    // FIXME: Handle environment options which effect driver behavior, somewhere
    // (client?). GCC_EXEC_PREFIX, COMPILER_PATH, LIBRARY_PATH, LPATH,
    // CC_PRINT_OPTIONS.

    // FIXME: What are we going to do with -V and -b?

    // FIXME: This stuff needs to go into the Compilation, not the driver.
    bool CCCPrintOptions = false, CCCPrintActions = false;

    const char **Start = argv + 1, **End = argv + argc;
    const char *HostTriple = DefaultHostTriple.c_str();

    InputArgList *Args = ParseArgStrings(Start, End);

    // -no-canonical-prefixes is used very early in main.
    Args->ClaimAllArgs(options::OPT_no_canonical_prefixes);

    // Extract -ccc args.
    //
    // FIXME: We need to figure out where this behavior should live. Most of it
    // should be outside in the client; the parts that aren't should have proper
    // options, either by introducing new ones or by overloading gcc ones like -V
    // or -b.
    CCCPrintOptions = Args->hasArg(options::OPT_ccc_print_options);
    CCCPrintActions = Args->hasArg(options::OPT_ccc_print_phases);
    CCCPrintBindings = Args->hasArg(options::OPT_ccc_print_bindings);
    CCCIsCXX = Args->hasArg(options::OPT_ccc_cxx) || CCCIsCXX;
    CCCEcho = Args->hasArg(options::OPT_ccc_echo);
    if (const Arg *A = Args->getLastArg(options::OPT_ccc_gcc_name))
        CCCGenericGCCName = A->getValue(*Args);
    CCCUseClangCXX = Args->hasFlag(options::OPT_ccc_clang_cxx,
                                   options::OPT_ccc_no_clang_cxx,
                                   CCCUseClangCXX);
    CCCUsePCH = Args->hasFlag(options::OPT_ccc_pch_is_pch,
                              options::OPT_ccc_pch_is_pth);
    CCCUseClang = !Args->hasArg(options::OPT_ccc_no_clang);
    CCCUseClangCPP = !Args->hasArg(options::OPT_ccc_no_clang_cpp);
    if (const Arg *A = Args->getLastArg(options::OPT_ccc_clang_archs)) {
        llvm::StringRef Cur = A->getValue(*Args);

        CCCClangArchs.clear();
        while (!Cur.empty()) {
            std::pair<llvm::StringRef, llvm::StringRef> Split = Cur.split(',');

            if (!Split.first.empty()) {
                llvm::Triple::ArchType Arch =
                    llvm::Triple(Split.first, "", "").getArch();

                if (Arch == llvm::Triple::UnknownArch)
                    Diag(clang::diag::err_drv_invalid_arch_name) << Split.first;

                CCCClangArchs.insert(Arch);
            }

            Cur = Split.second;
        }
    }
    if (const Arg *A = Args->getLastArg(options::OPT_ccc_host_triple))
        HostTriple = A->getValue(*Args);
    if (const Arg *A = Args->getLastArg(options::OPT_ccc_install_dir))
        Dir = A->getValue(*Args);

    Host = GetHostInfo(HostTriple);

    // The compilation takes ownership of Args.
    Compilation *C = new Compilation(*this, *Host->CreateToolChain(*Args), Args);

    // FIXME: This behavior shouldn't be here.
    if (CCCPrintOptions) {
        PrintOptions(C->getArgs());
        return C;
    }

    if (!HandleImmediateArgs(*C))
        return C;

    // Construct the list of abstract actions to perform for this compilation. We
    // avoid passing a Compilation here simply to enforce the abstraction that
    // pipelining is not host or toolchain dependent (other than the driver driver
    // test).
    if (Host->useDriverDriver())
        BuildUniversalActions(C->getArgs(), C->getActions());
    else
        BuildActions(C->getArgs(), C->getActions());

    if (CCCPrintActions) {
        PrintActions(*C);
        return C;
    }

    BuildJobs(*C);

    return C;
}
示例#12
0
bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
                                         ArrayRef<const char *> Argv,
                                         DiagnosticsEngine &Diags) {
  bool Success = true;

  // Parse the arguments.
  std::unique_ptr<OptTable> OptTbl(createDriverOptTable());

  const unsigned IncludedFlagsBitmask = options::CC1AsOption;
  unsigned MissingArgIndex, MissingArgCount;
  InputArgList Args = OptTbl->ParseArgs(Argv, MissingArgIndex, MissingArgCount,
                                        IncludedFlagsBitmask);

  // Check for missing argument error.
  if (MissingArgCount) {
    Diags.Report(diag::err_drv_missing_argument)
        << Args.getArgString(MissingArgIndex) << MissingArgCount;
    Success = false;
  }

  // Issue errors on unknown arguments.
  for (const Arg *A : Args.filtered(OPT_UNKNOWN)) {
    Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(Args);
    Success = false;
  }

  // Construct the invocation.

  // Target Options
  Opts.Triple = llvm::Triple::normalize(Args.getLastArgValue(OPT_triple));
  Opts.CPU = Args.getLastArgValue(OPT_target_cpu);
  Opts.Features = Args.getAllArgValues(OPT_target_feature);

  // Use the default target triple if unspecified.
  if (Opts.Triple.empty())
    Opts.Triple = llvm::sys::getDefaultTargetTriple();

  // Language Options
  Opts.IncludePaths = Args.getAllArgValues(OPT_I);
  Opts.NoInitialTextSection = Args.hasArg(OPT_n);
  Opts.SaveTemporaryLabels = Args.hasArg(OPT_msave_temp_labels);
  // Any DebugInfoKind implies GenDwarfForAssembly.
  Opts.GenDwarfForAssembly = Args.hasArg(OPT_debug_info_kind_EQ);
  Opts.CompressDebugSections = Args.hasArg(OPT_compress_debug_sections);
  Opts.RelaxELFRelocations = Args.hasArg(OPT_mrelax_relocations);
  Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 2, Diags);
  Opts.DwarfDebugFlags = Args.getLastArgValue(OPT_dwarf_debug_flags);
  Opts.DwarfDebugProducer = Args.getLastArgValue(OPT_dwarf_debug_producer);
  Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir);
  Opts.MainFileName = Args.getLastArgValue(OPT_main_file_name);

  // Frontend Options
  if (Args.hasArg(OPT_INPUT)) {
    bool First = true;
    for (arg_iterator it = Args.filtered_begin(OPT_INPUT),
                      ie = Args.filtered_end();
         it != ie; ++it, First = false) {
      const Arg *A = it;
      if (First)
        Opts.InputFile = A->getValue();
      else {
        Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(Args);
        Success = false;
      }
    }
  }
  Opts.LLVMArgs = Args.getAllArgValues(OPT_mllvm);
  Opts.OutputPath = Args.getLastArgValue(OPT_o);
  if (Arg *A = Args.getLastArg(OPT_filetype)) {
    StringRef Name = A->getValue();
    unsigned OutputType = StringSwitch<unsigned>(Name)
      .Case("asm", FT_Asm)
      .Case("null", FT_Null)
      .Case("obj", FT_Obj)
      .Default(~0U);
    if (OutputType == ~0U) {
      Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
      Success = false;
    } else
      Opts.OutputType = FileType(OutputType);
  }
  Opts.ShowHelp = Args.hasArg(OPT_help);
  Opts.ShowVersion = Args.hasArg(OPT_version);

  // Transliterate Options
  Opts.OutputAsmVariant =
      getLastArgIntValue(Args, OPT_output_asm_variant, 0, Diags);
  Opts.ShowEncoding = Args.hasArg(OPT_show_encoding);
  Opts.ShowInst = Args.hasArg(OPT_show_inst);

  // Assemble Options
  Opts.RelaxAll = Args.hasArg(OPT_mrelax_all);
  Opts.NoExecStack = Args.hasArg(OPT_mno_exec_stack);
  Opts.FatalWarnings = Args.hasArg(OPT_massembler_fatal_warnings);
  Opts.RelocationModel = Args.getLastArgValue(OPT_mrelocation_model, "pic");
  Opts.IncrementalLinkerCompatible =
      Args.hasArg(OPT_mincremental_linker_compatible);

  return Success;
}