diff options
Diffstat (limited to 'tools/driver/cc1as_main.cpp')
-rw-r--r-- | tools/driver/cc1as_main.cpp | 147 |
1 files changed, 85 insertions, 62 deletions
diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp index 31cd236b84ce..e41bc9f824e8 100644 --- a/tools/driver/cc1as_main.cpp +++ b/tools/driver/cc1as_main.cpp @@ -14,13 +14,11 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" -#include "clang/Driver/CC1AsOptions.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Frontend/Utils.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" #include "llvm/IR/DataLayout.h" @@ -35,6 +33,7 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCTargetAsmParser.h" +#include "llvm/MC/MCTargetOptions.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/OptTable.h" @@ -53,9 +52,11 @@ #include "llvm/Support/TargetSelect.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Support/system_error.h" +#include <memory> +#include <system_error> using namespace clang; using namespace clang::driver; +using namespace clang::driver::options; using namespace llvm; using namespace llvm::opt; @@ -85,6 +86,8 @@ struct AssemblerInvocation { unsigned NoInitialTextSection : 1; unsigned SaveTemporaryLabels : 1; unsigned GenDwarfForAssembly : 1; + unsigned CompressDebugSections : 1; + unsigned DwarfVersion; std::string DwarfDebugFlags; std::string DwarfDebugProducer; std::string DebugCompilationDir; @@ -135,6 +138,7 @@ public: ShowEncoding = 0; RelaxAll = 0; NoExecStack = 0; + DwarfVersion = 3; } static bool CreateFromArgs(AssemblerInvocation &Res, const char **ArgBegin, @@ -147,26 +151,29 @@ 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()); + std::unique_ptr<OptTable> OptTbl(createDriverOptTable()); + + const unsigned IncludedFlagsBitmask = options::CC1AsOption; unsigned MissingArgIndex, MissingArgCount; - OwningPtr<InputArgList> Args( - OptTbl->ParseArgs(ArgBegin, ArgEnd,MissingArgIndex, MissingArgCount)); + std::unique_ptr<InputArgList> Args( + OptTbl->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount, + IncludedFlagsBitmask)); // Check for missing argument error. if (MissingArgCount) { Diags.Report(diag::err_drv_missing_argument) - << Args->getArgString(MissingArgIndex) << MissingArgCount; + << 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) { - Diags.Report(diag::err_drv_unknown_argument) << (*it) ->getAsString(*Args); + for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN), + ie = Args->filtered_end(); + it != ie; ++it) { + Diags.Report(diag::err_drv_unknown_argument) << (*it)->getAsString(*Args); Success = false; } @@ -185,7 +192,14 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, Opts.IncludePaths = Args->getAllArgValues(OPT_I); Opts.NoInitialTextSection = Args->hasArg(OPT_n); Opts.SaveTemporaryLabels = Args->hasArg(OPT_msave_temp_labels); - Opts.GenDwarfForAssembly = Args->hasArg(OPT_g); + Opts.GenDwarfForAssembly = Args->hasArg(OPT_g_Flag); + Opts.CompressDebugSections = Args->hasArg(OPT_compress_debug_sections); + if (Args->hasArg(OPT_gdwarf_2)) + Opts.DwarfVersion = 2; + if (Args->hasArg(OPT_gdwarf_3)) + Opts.DwarfVersion = 3; + if (Args->hasArg(OPT_gdwarf_4)) + Opts.DwarfVersion = 4; Opts.DwarfDebugFlags = Args->getLastArgValue(OPT_dwarf_debug_flags); Opts.DwarfDebugProducer = Args->getLastArgValue(OPT_dwarf_debug_producer); Opts.DebugCompilationDir = Args->getLastArgValue(OPT_fdebug_compilation_dir); @@ -251,11 +265,12 @@ static formatted_raw_ostream *GetOutputStream(AssemblerInvocation &Opts, std::string Error; raw_fd_ostream *Out = new raw_fd_ostream(Opts.OutputPath.c_str(), Error, - (Binary ? sys::fs::F_Binary : sys::fs::F_None)); + (Binary ? sys::fs::F_None : sys::fs::F_Text)); if (!Error.empty()) { Diags.Report(diag::err_fe_unable_to_open_output) << Opts.OutputPath << Error; - return 0; + delete Out; + return nullptr; } return new formatted_raw_ostream(*Out, formatted_raw_ostream::DELETE_STREAM); @@ -265,43 +280,48 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, DiagnosticsEngine &Diags) { // Get the target specific parser. std::string Error; - const Target *TheTarget(TargetRegistry::lookupTarget(Opts.Triple, Error)); - if (!TheTarget) { - Diags.Report(diag::err_target_unknown_triple) << Opts.Triple; - return false; - } + const Target *TheTarget = TargetRegistry::lookupTarget(Opts.Triple, Error); + if (!TheTarget) + return Diags.Report(diag::err_target_unknown_triple) << Opts.Triple; - OwningPtr<MemoryBuffer> BufferPtr; - if (error_code ec = MemoryBuffer::getFileOrSTDIN(Opts.InputFile, BufferPtr)) { - Error = ec.message(); - Diags.Report(diag::err_fe_error_reading) << Opts.InputFile; - return false; + ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer = + MemoryBuffer::getFileOrSTDIN(Opts.InputFile); + + if (std::error_code EC = Buffer.getError()) { + Error = EC.message(); + return Diags.Report(diag::err_fe_error_reading) << Opts.InputFile; } - MemoryBuffer *Buffer = BufferPtr.take(); SourceMgr SrcMgr; // Tell SrcMgr about this buffer, which is what the parser will pick up. - SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); + SrcMgr.AddNewSourceBuffer(Buffer->release(), SMLoc()); // Record the location of the include directories so that the lexer can find // it later. SrcMgr.setIncludeDirs(Opts.IncludePaths); - OwningPtr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple)); + std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple)); assert(MRI && "Unable to create target register info!"); - OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, Opts.Triple)); + std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, Opts.Triple)); assert(MAI && "Unable to create target asm info!"); + // Ensure MCAsmInfo initialization occurs before any use, otherwise sections + // may be created with a combination of default and explicit settings. + if (Opts.CompressDebugSections) + MAI->setCompressDebugSections(true); + bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj; - formatted_raw_ostream *Out = GetOutputStream(Opts, Diags, IsBinary); + std::unique_ptr<formatted_raw_ostream> Out( + GetOutputStream(Opts, Diags, IsBinary)); if (!Out) - return false; + return true; // 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()); + std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo()); + MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr); // FIXME: Assembler behavior can change with -static. MOFI->InitMCObjectFileInfo(Opts.Triple, @@ -318,6 +338,7 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, Ctx.setCompilationDir(Opts.DebugCompilationDir); if (!Opts.MainFileName.empty()) Ctx.setMainFileName(StringRef(Opts.MainFileName)); + Ctx.setDwarfVersion(Opts.DwarfVersion); // Build up the feature string from the target feature list. std::string FS; @@ -327,26 +348,24 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, FS += "," + Opts.Features[i]; } - OwningPtr<MCStreamer> Str; + std::unique_ptr<MCStreamer> Str; - OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo()); - OwningPtr<MCSubtargetInfo> - STI(TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS)); + std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo()); + std::unique_ptr<MCSubtargetInfo> 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, *MCII, *MRI, *STI); - MCCodeEmitter *CE = 0; - MCAsmBackend *MAB = 0; + MCCodeEmitter *CE = nullptr; + MCAsmBackend *MAB = nullptr; if (Opts.ShowEncoding) { CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx); MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple, Opts.CPU); } Str.reset(TheTarget->createAsmStreamer(Ctx, *Out, /*asmverbose*/true, - /*useLoc*/ true, - /*useCFI*/ true, /*useDwarfDirectory*/ true, IP, CE, MAB, Opts.ShowInst)); @@ -359,31 +378,36 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple, Opts.CPU); Str.reset(TheTarget->createMCObjectStreamer(Opts.Triple, Ctx, *MAB, *Out, - CE, Opts.RelaxAll, + CE, *STI, Opts.RelaxAll, Opts.NoExecStack)); Str.get()->InitSections(); } - OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx, - *Str.get(), *MAI)); - OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(*STI, *Parser, *MCII)); - if (!TAP) { - Diags.Report(diag::err_target_unknown_triple) << Opts.Triple; - return false; - } + bool Failed = false; + + std::unique_ptr<MCAsmParser> Parser( + createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI)); - Parser->setTargetParser(*TAP.get()); + // FIXME: init MCTargetOptions from sanitizer flags here. + MCTargetOptions Options; + std::unique_ptr<MCTargetAsmParser> TAP( + TheTarget->createMCAsmParser(*STI, *Parser, *MCII, Options)); + if (!TAP) + Failed = Diags.Report(diag::err_target_unknown_triple) << Opts.Triple; - bool Success = !Parser->Run(Opts.NoInitialTextSection); + if (!Failed) { + Parser->setTargetParser(*TAP.get()); + Failed = Parser->Run(Opts.NoInitialTextSection); + } - // Close the output. - delete Out; + // Close the output stream early. + Out.reset(); - // Delete output on errors. - if (!Success && Opts.OutputPath != "-") + // Delete output file if there were errors. + if (Failed && Opts.OutputPath != "-") sys::fs::remove(Opts.OutputPath); - return Success; + return Failed; } static void LLVMErrorHandler(void *UserData, const std::string &Message, @@ -426,10 +450,10 @@ int cc1as_main(const char **ArgBegin, const char **ArgEnd, if (!AssemblerInvocation::CreateFromArgs(Asm, ArgBegin, ArgEnd, Diags)) return 1; - // Honor -help. if (Asm.ShowHelp) { - OwningPtr<OptTable> Opts(driver::createCC1AsOptTable()); - Opts->PrintHelp(llvm::outs(), "clang -cc1as", "Clang Integrated Assembler"); + std::unique_ptr<OptTable> Opts(driver::createDriverOptTable()); + Opts->PrintHelp(llvm::outs(), "clang -cc1as", "Clang Integrated Assembler", + /*Include=*/driver::options::CC1AsOption, /*Exclude=*/0); return 0; } @@ -450,18 +474,17 @@ int cc1as_main(const char **ArgBegin, const char **ArgEnd, Args[0] = "clang (LLVM option parsing)"; for (unsigned i = 0; i != NumArgs; ++i) Args[i + 1] = Asm.LLVMArgs[i].c_str(); - Args[NumArgs + 1] = 0; + Args[NumArgs + 1] = nullptr; llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args); } // Execute the invocation, unless there were parsing errors. - bool Success = false; - if (!Diags.hasErrorOccurred()) - Success = ExecuteAssembler(Asm, Diags); + bool Failed = Diags.hasErrorOccurred() || ExecuteAssembler(Asm, Diags); // If any timers were active but haven't been destroyed yet, print their // results now. TimerGroup::printAll(errs()); - return !Success; + return !!Failed; } + |