diff options
Diffstat (limited to 'tools/driver/cc1as_main.cpp')
-rw-r--r-- | tools/driver/cc1as_main.cpp | 80 |
1 files changed, 62 insertions, 18 deletions
diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp index 7cc42aa..508d6da 100644 --- a/tools/driver/cc1as_main.cpp +++ b/tools/driver/cc1as_main.cpp @@ -63,8 +63,17 @@ struct AssemblerInvocation { /// @name Target Options /// @{ + /// The name of the target triple to assemble for. std::string Triple; + /// If given, the name of the target CPU to determine which instructions + /// are legal. + std::string CPU; + + /// The list of target specific features to enable or disable -- this should + /// be a list of strings starting with '+' or '-'. + std::vector<std::string> Features; + /// @} /// @name Language Options /// @{ @@ -72,6 +81,8 @@ struct AssemblerInvocation { std::vector<std::string> IncludePaths; unsigned NoInitialTextSection : 1; unsigned SaveTemporaryLabels : 1; + unsigned GenDwarfForAssembly : 1; + std::string DwarfDebugFlags; /// @} /// @name Frontend Options @@ -120,17 +131,19 @@ public: NoExecStack = 0; } - static void CreateFromArgs(AssemblerInvocation &Res, const char **ArgBegin, + static bool CreateFromArgs(AssemblerInvocation &Res, const char **ArgBegin, const char **ArgEnd, DiagnosticsEngine &Diags); }; } -void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, +bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, const char **ArgBegin, const char **ArgEnd, DiagnosticsEngine &Diags) { using namespace clang::driver::cc1asoptions; + bool Success = true; + // Parse the arguments. OwningPtr<OptTable> OptTbl(createCC1AsOptTable()); unsigned MissingArgIndex, MissingArgCount; @@ -138,26 +151,36 @@ void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, OptTbl->ParseArgs(ArgBegin, ArgEnd,MissingArgIndex, MissingArgCount)); // Check for missing argument error. - if (MissingArgCount) + if (MissingArgCount) { Diags.Report(diag::err_drv_missing_argument) << Args->getArgString(MissingArgIndex) << MissingArgCount; + Success = false; + } // Issue errors on unknown arguments. for (arg_iterator it = Args->filtered_begin(cc1asoptions::OPT_UNKNOWN), - ie = Args->filtered_end(); it != ie; ++it) + ie = Args->filtered_end(); it != ie; ++it) { Diags.Report(diag::err_drv_unknown_argument) << (*it) ->getAsString(*Args); + Success = false; + } // Construct the invocation. // Target Options - Opts.Triple = Triple::normalize(Args->getLastArgValue(OPT_triple)); - if (Opts.Triple.empty()) // Use the host triple if unspecified. - Opts.Triple = sys::getHostTriple(); + 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_L); + Opts.GenDwarfForAssembly = Args->hasArg(OPT_g); + Opts.DwarfDebugFlags = Args->getLastArgValue(OPT_dwarf_debug_flags); // Frontend Options if (Args->hasArg(OPT_INPUT)) { @@ -167,8 +190,10 @@ void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, const Arg *A = it; if (First) Opts.InputFile = A->getValue(*Args); - else + else { Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(*Args); + Success = false; + } } } Opts.LLVMArgs = Args->getAllArgValues(OPT_mllvm); @@ -182,10 +207,11 @@ void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, .Case("null", FT_Null) .Case("obj", FT_Obj) .Default(~0U); - if (OutputType == ~0U) + if (OutputType == ~0U) { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(*Args) << Name; - else + Success = false; + } else Opts.OutputType = FileType(OutputType); } Opts.ShowHelp = Args->hasArg(OPT_help); @@ -200,6 +226,8 @@ void AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, // Assemble Options Opts.RelaxAll = Args->hasArg(OPT_relax_all); Opts.NoExecStack = Args->hasArg(OPT_no_exec_stack); + + return Success; } static formatted_raw_ostream *GetOutputStream(AssemblerInvocation &Opts, @@ -267,23 +295,36 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and // MCObjectFileInfo needs a MCContext reference in order to initialize itself. OwningPtr<MCObjectFileInfo> MOFI(new MCObjectFileInfo()); - MCContext Ctx(*MAI, *MRI, MOFI.get()); + MCContext Ctx(*MAI, *MRI, MOFI.get(), &SrcMgr); // FIXME: Assembler behavior can change with -static. MOFI->InitMCObjectFileInfo(Opts.Triple, Reloc::Default, CodeModel::Default, Ctx); if (Opts.SaveTemporaryLabels) Ctx.setAllowTemporaryLabels(false); + if (Opts.GenDwarfForAssembly) + Ctx.setGenDwarfForAssembly(true); + if (!Opts.DwarfDebugFlags.empty()) + Ctx.setDwarfDebugFlags(StringRef(Opts.DwarfDebugFlags)); + + // Build up the feature string from the target feature list. + std::string FS; + if (!Opts.Features.empty()) { + FS = Opts.Features[0]; + for (unsigned i = 1, e = Opts.Features.size(); i != e; ++i) + FS += "," + Opts.Features[i]; + } OwningPtr<MCStreamer> Str; OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo()); OwningPtr<MCSubtargetInfo> - STI(TheTarget->createMCSubtargetInfo(Opts.Triple, "", "")); + STI(TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS)); // FIXME: There is a bit of code duplication with addPassesToEmitFile. if (Opts.OutputType == AssemblerInvocation::FT_Asm) { MCInstPrinter *IP = - TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI, *STI); + TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI, *MCII, *MRI, + *STI); MCCodeEmitter *CE = 0; MCAsmBackend *MAB = 0; if (Opts.ShowEncoding) { @@ -292,7 +333,9 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, } Str.reset(TheTarget->createAsmStreamer(Ctx, *Out, /*asmverbose*/true, /*useLoc*/ true, - /*useCFI*/ true, IP, CE, MAB, + /*useCFI*/ true, + /*useDwarfDirectory*/ true, + IP, CE, MAB, Opts.ShowInst)); } else if (Opts.OutputType == AssemblerInvocation::FT_Null) { Str.reset(createNullStreamer(Ctx)); @@ -354,7 +397,7 @@ int cc1as_main(const char **ArgBegin, const char **ArgEnd, TextDiagnosticPrinter *DiagClient = new TextDiagnosticPrinter(errs(), DiagnosticOptions()); DiagClient->setPrefix("clang -cc1as"); - llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); DiagnosticsEngine Diags(DiagID, DiagClient); // Set an error handler, so that any LLVM backend diagnostics go through our @@ -364,11 +407,12 @@ int cc1as_main(const char **ArgBegin, const char **ArgEnd, // Parse the arguments. AssemblerInvocation Asm; - AssemblerInvocation::CreateFromArgs(Asm, ArgBegin, ArgEnd, Diags); + if (!AssemblerInvocation::CreateFromArgs(Asm, ArgBegin, ArgEnd, Diags)) + return 1; // Honor -help. if (Asm.ShowHelp) { - llvm::OwningPtr<driver::OptTable> Opts(driver::createCC1AsOptTable()); + OwningPtr<driver::OptTable> Opts(driver::createCC1AsOptTable()); Opts->PrintHelp(llvm::outs(), "clang -cc1as", "Clang Integrated Assembler"); return 0; } @@ -391,7 +435,7 @@ int cc1as_main(const char **ArgBegin, const char **ArgEnd, for (unsigned i = 0; i != NumArgs; ++i) Args[i + 1] = Asm.LLVMArgs[i].c_str(); Args[NumArgs + 1] = 0; - llvm::cl::ParseCommandLineOptions(NumArgs + 1, const_cast<char **>(Args)); + llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args); } // Execute the invocation, unless there were parsing errors. |