forked from OSchip/llvm-project
Move input kind identification (-x) into FrontendOptions.
llvm-svn: 87066
This commit is contained in:
parent
3c55718016
commit
27b19dc1b5
|
@ -11,6 +11,7 @@
|
|||
#define LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H
|
||||
|
||||
#include "clang/Frontend/CommandLineSourceLoc.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -19,6 +20,21 @@ namespace clang {
|
|||
/// FrontendOptions - Options for controlling the behavior of the frontend.
|
||||
class FrontendOptions {
|
||||
public:
|
||||
enum InputKind {
|
||||
IK_None,
|
||||
IK_Asm,
|
||||
IK_C,
|
||||
IK_CXX,
|
||||
IK_ObjC,
|
||||
IK_ObjCXX,
|
||||
IK_PreprocessedC,
|
||||
IK_PreprocessedCXX,
|
||||
IK_PreprocessedObjC,
|
||||
IK_PreprocessedObjCXX,
|
||||
IK_OpenCL,
|
||||
IK_AST
|
||||
};
|
||||
|
||||
unsigned DebugCodeCompletionPrinter : 1; ///< Use the debug printer for code
|
||||
/// completion results.
|
||||
unsigned DisableFree : 1; ///< Disable memory freeing on exit.
|
||||
|
@ -44,8 +60,8 @@ public:
|
|||
/// If given, the name of the target ABI to use.
|
||||
std::string TargetABI;
|
||||
|
||||
/// The input files.
|
||||
std::vector<std::string> InputFilenames;
|
||||
/// The input files and their types.
|
||||
std::vector<std::pair<InputKind, std::string> > Inputs;
|
||||
|
||||
/// The output file, if any.
|
||||
std::string OutputFile;
|
||||
|
@ -70,6 +86,13 @@ public:
|
|||
ShowStats = 0;
|
||||
ShowTimers = 0;
|
||||
}
|
||||
|
||||
/// getInputKindForExtension - Return the appropriate input kind for a file
|
||||
/// extension. For example, "c" would return IK_C.
|
||||
///
|
||||
/// \return The input kind for the extension, or IK_None if the extension is
|
||||
/// not recognized.
|
||||
static InputKind getInputKindForExtension(llvm::StringRef Extension);
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
|
|
@ -11,6 +11,7 @@ add_clang_library(clangFrontend
|
|||
DiagChecker.cpp
|
||||
DocumentXML.cpp
|
||||
FixItRewriter.cpp
|
||||
FrontendOptions.cpp
|
||||
GeneratePCH.cpp
|
||||
HTMLDiagnostics.cpp
|
||||
HTMLPrint.cpp
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
//===--- FrontendOptions.cpp ----------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Frontend/FrontendOptions.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
using namespace clang;
|
||||
|
||||
FrontendOptions::InputKind
|
||||
FrontendOptions::getInputKindForExtension(llvm::StringRef Extension) {
|
||||
return llvm::StringSwitch<InputKind>(Extension)
|
||||
.Case("ast", IK_AST)
|
||||
.Case("c", IK_C)
|
||||
.Cases("S", "s", IK_Asm)
|
||||
.Case("i", IK_PreprocessedC)
|
||||
.Case("ii", IK_PreprocessedCXX)
|
||||
.Case("m", IK_ObjC)
|
||||
.Case("mi", IK_PreprocessedObjC)
|
||||
.Cases("mm", "M", IK_ObjCXX)
|
||||
.Case("mii", IK_PreprocessedObjCXX)
|
||||
.Case("C", IK_CXX)
|
||||
.Cases("C", "cc", "cp", IK_CXX)
|
||||
.Cases("cpp", "CPP", "c++", "cxx", IK_CXX)
|
||||
.Case("cl", IK_OpenCL)
|
||||
.Default(IK_C);
|
||||
}
|
|
@ -321,6 +321,44 @@ 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>"));
|
||||
|
||||
|
@ -791,7 +829,6 @@ void clang::InitializeFrontendOptions(FrontendOptions &Opts) {
|
|||
Opts.EmptyInputOnly = EmptyInputOnly;
|
||||
Opts.FixItAll = FixItAll;
|
||||
Opts.FixItLocations = FixItAtLocations;
|
||||
Opts.InputFilenames = InputFilenames;
|
||||
Opts.OutputFile = OutputFile;
|
||||
Opts.RelocatablePCH = RelocatablePCH;
|
||||
Opts.ShowMacrosInCodeCompletion = CodeCompletionWantsMacros;
|
||||
|
@ -802,8 +839,21 @@ void clang::InitializeFrontendOptions(FrontendOptions &Opts) {
|
|||
Opts.ViewClassInheritance = InheritanceViewCls;
|
||||
|
||||
// '-' is the default input if none is given.
|
||||
if (Opts.InputFilenames.empty())
|
||||
Opts.InputFilenames.push_back("-");
|
||||
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,
|
||||
|
@ -972,44 +1022,47 @@ void clang::InitializePreprocessorOptions(PreprocessorOptions &Opts) {
|
|||
Opts.addInclude(*OrderedPaths[i].second);
|
||||
}
|
||||
|
||||
void clang::InitializeLangOptions(LangOptions &Options, LangKind LK,
|
||||
void clang::InitializeLangOptions(LangOptions &Options,
|
||||
FrontendOptions::InputKind IK,
|
||||
TargetInfo &Target,
|
||||
const CodeGenOptions &CodeGenOpts) {
|
||||
using namespace langoptions;
|
||||
|
||||
bool NoPreprocess = false;
|
||||
|
||||
switch (LK) {
|
||||
default: assert(0 && "Unknown language kind!");
|
||||
case langkind_asm_cpp:
|
||||
switch (IK) {
|
||||
case FrontendOptions::IK_None:
|
||||
case FrontendOptions::IK_AST:
|
||||
assert(0 && "Invalid input kind!");
|
||||
case FrontendOptions::IK_Asm:
|
||||
Options.AsmPreprocessor = 1;
|
||||
// FALLTHROUGH
|
||||
case langkind_c_cpp:
|
||||
case FrontendOptions::IK_PreprocessedC:
|
||||
NoPreprocess = true;
|
||||
// FALLTHROUGH
|
||||
case langkind_c:
|
||||
case FrontendOptions::IK_C:
|
||||
// Do nothing.
|
||||
break;
|
||||
case langkind_cxx_cpp:
|
||||
case FrontendOptions::IK_PreprocessedCXX:
|
||||
NoPreprocess = true;
|
||||
// FALLTHROUGH
|
||||
case langkind_cxx:
|
||||
case FrontendOptions::IK_CXX:
|
||||
Options.CPlusPlus = 1;
|
||||
break;
|
||||
case langkind_objc_cpp:
|
||||
case FrontendOptions::IK_PreprocessedObjC:
|
||||
NoPreprocess = true;
|
||||
// FALLTHROUGH
|
||||
case langkind_objc:
|
||||
case FrontendOptions::IK_ObjC:
|
||||
Options.ObjC1 = Options.ObjC2 = 1;
|
||||
break;
|
||||
case langkind_objcxx_cpp:
|
||||
case FrontendOptions::IK_PreprocessedObjCXX:
|
||||
NoPreprocess = true;
|
||||
// FALLTHROUGH
|
||||
case langkind_objcxx:
|
||||
case FrontendOptions::IK_ObjCXX:
|
||||
Options.ObjC1 = Options.ObjC2 = 1;
|
||||
Options.CPlusPlus = 1;
|
||||
break;
|
||||
case langkind_ocl:
|
||||
case FrontendOptions::IK_OpenCL:
|
||||
Options.OpenCL = 1;
|
||||
Options.AltiVec = 1;
|
||||
Options.CXXOperatorNames = 1;
|
||||
|
@ -1044,23 +1097,24 @@ void clang::InitializeLangOptions(LangOptions &Options, LangKind LK,
|
|||
|
||||
if (LangStd == lang_unspecified) {
|
||||
// Based on the base language, pick one.
|
||||
switch (LK) {
|
||||
case langkind_ast: assert(0 && "Invalid call for AST inputs");
|
||||
case lang_unspecified: assert(0 && "Unknown base language");
|
||||
case langkind_ocl:
|
||||
switch (IK) {
|
||||
case FrontendOptions::IK_None:
|
||||
case FrontendOptions::IK_AST:
|
||||
assert(0 && "Invalid input kind!");
|
||||
case FrontendOptions::IK_OpenCL:
|
||||
LangStd = lang_c99;
|
||||
break;
|
||||
case langkind_c:
|
||||
case langkind_asm_cpp:
|
||||
case langkind_c_cpp:
|
||||
case langkind_objc:
|
||||
case langkind_objc_cpp:
|
||||
case FrontendOptions::IK_Asm:
|
||||
case FrontendOptions::IK_C:
|
||||
case FrontendOptions::IK_PreprocessedC:
|
||||
case FrontendOptions::IK_ObjC:
|
||||
case FrontendOptions::IK_PreprocessedObjC:
|
||||
LangStd = lang_gnu99;
|
||||
break;
|
||||
case langkind_cxx:
|
||||
case langkind_cxx_cpp:
|
||||
case langkind_objcxx:
|
||||
case langkind_objcxx_cpp:
|
||||
case FrontendOptions::IK_CXX:
|
||||
case FrontendOptions::IK_PreprocessedCXX:
|
||||
case FrontendOptions::IK_ObjCXX:
|
||||
case FrontendOptions::IK_PreprocessedObjCXX:
|
||||
LangStd = lang_gnucxx98;
|
||||
break;
|
||||
}
|
||||
|
@ -1139,7 +1193,7 @@ void clang::InitializeLangOptions(LangOptions &Options, LangKind LK,
|
|||
// Default to not accepting '$' in identifiers when preprocessing assembler,
|
||||
// but do accept when preprocessing C. FIXME: these defaults are right for
|
||||
// darwin, are they right everywhere?
|
||||
Options.DollarIdents = LK != langkind_asm_cpp;
|
||||
Options.DollarIdents = IK != FrontendOptions::IK_Asm;
|
||||
if (DollarsInIdents.getPosition()) // Explicit setting overrides default.
|
||||
Options.DollarIdents = DollarsInIdents;
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#ifndef LLVM_CLANGCC_OPTIONS_H
|
||||
#define LLVM_CLANGCC_OPTIONS_H
|
||||
|
||||
#include "clang/Frontend/FrontendOptions.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
namespace clang {
|
||||
|
@ -25,21 +26,6 @@ class PreprocessorOptions;
|
|||
class PreprocessorOutputOptions;
|
||||
class TargetInfo;
|
||||
|
||||
enum LangKind {
|
||||
langkind_unspecified,
|
||||
langkind_c,
|
||||
langkind_c_cpp,
|
||||
langkind_asm_cpp,
|
||||
langkind_cxx,
|
||||
langkind_cxx_cpp,
|
||||
langkind_objc,
|
||||
langkind_objc_cpp,
|
||||
langkind_objcxx,
|
||||
langkind_objcxx_cpp,
|
||||
langkind_ocl,
|
||||
langkind_ast
|
||||
};
|
||||
|
||||
void InitializeAnalyzerOptions(AnalyzerOptions &Opts);
|
||||
|
||||
void InitializeDependencyOutputOptions(DependencyOutputOptions &Opts);
|
||||
|
@ -55,7 +41,8 @@ void InitializeHeaderSearchOptions(HeaderSearchOptions &Opts,
|
|||
llvm::StringRef BuiltinIncludePath,
|
||||
const LangOptions &Lang);
|
||||
|
||||
void InitializeLangOptions(LangOptions &Options, LangKind LK,
|
||||
void InitializeLangOptions(LangOptions &Options,
|
||||
FrontendOptions::InputKind LK,
|
||||
TargetInfo &Target,
|
||||
const CodeGenOptions &CodeGenOpts);
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/Config/config.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
@ -165,40 +164,6 @@ ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore,
|
|||
"Rewrite Blocks to C"),
|
||||
clEnumValEnd));
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Language Options
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static llvm::cl::opt<LangKind>
|
||||
BaseLang("x", llvm::cl::desc("Base language to compile"),
|
||||
llvm::cl::init(langkind_unspecified),
|
||||
llvm::cl::values(clEnumValN(langkind_c, "c", "C"),
|
||||
clEnumValN(langkind_ocl, "cl", "OpenCL C"),
|
||||
clEnumValN(langkind_cxx, "c++", "C++"),
|
||||
clEnumValN(langkind_objc, "objective-c", "Objective C"),
|
||||
clEnumValN(langkind_objcxx,"objective-c++","Objective C++"),
|
||||
clEnumValN(langkind_c_cpp, "cpp-output",
|
||||
"Preprocessed C"),
|
||||
clEnumValN(langkind_asm_cpp, "assembler-with-cpp",
|
||||
"Preprocessed asm"),
|
||||
clEnumValN(langkind_cxx_cpp, "c++-cpp-output",
|
||||
"Preprocessed C++"),
|
||||
clEnumValN(langkind_objc_cpp, "objective-c-cpp-output",
|
||||
"Preprocessed Objective C"),
|
||||
clEnumValN(langkind_objcxx_cpp, "objective-c++-cpp-output",
|
||||
"Preprocessed Objective C++"),
|
||||
clEnumValN(langkind_c, "c-header",
|
||||
"C header"),
|
||||
clEnumValN(langkind_objc, "objective-c-header",
|
||||
"Objective-C header"),
|
||||
clEnumValN(langkind_cxx, "c++-header",
|
||||
"C++ header"),
|
||||
clEnumValN(langkind_objcxx, "objective-c++-header",
|
||||
"Objective-C++ header"),
|
||||
clEnumValN(langkind_ast, "ast",
|
||||
"Clang AST"),
|
||||
clEnumValEnd));
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Utility Methods
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -860,43 +825,6 @@ static void LLVMErrorHandler(void *UserData, const std::string &Message) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
static LangKind GetLanguage(const std::vector<std::string> &Inputs) {
|
||||
// If -x was given, that's the language.
|
||||
if (BaseLang != langkind_unspecified)
|
||||
return BaseLang;
|
||||
|
||||
// Otherwise guess it from the input filenames;
|
||||
LangKind LK = langkind_unspecified;
|
||||
for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
|
||||
llvm::StringRef Name(Inputs[i]);
|
||||
LangKind ThisKind = llvm::StringSwitch<LangKind>(Name.rsplit('.').second)
|
||||
.Case("ast", langkind_ast)
|
||||
.Case("c", langkind_c)
|
||||
.Cases("S", "s", langkind_asm_cpp)
|
||||
.Case("i", langkind_c_cpp)
|
||||
.Case("ii", langkind_cxx_cpp)
|
||||
.Case("m", langkind_objc)
|
||||
.Case("mi", langkind_objc_cpp)
|
||||
.Cases("mm", "M", langkind_objcxx)
|
||||
.Case("mii", langkind_objcxx_cpp)
|
||||
.Case("C", langkind_cxx)
|
||||
.Cases("C", "cc", "cp", langkind_cxx)
|
||||
.Cases("cpp", "CPP", "c++", "cxx", langkind_cxx)
|
||||
.Case("cl", langkind_ocl)
|
||||
.Default(langkind_c);
|
||||
|
||||
if (LK != langkind_unspecified && ThisKind != LK) {
|
||||
llvm::errs() << "error: cannot have multiple input files of distinct "
|
||||
<< "language kinds without -x\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
LK = ThisKind;
|
||||
}
|
||||
|
||||
return LK;
|
||||
}
|
||||
|
||||
static TargetInfo *
|
||||
ConstructCompilerInvocation(CompilerInvocation &Opts, Diagnostic &Diags,
|
||||
const char *Argv0,
|
||||
|
@ -931,14 +859,23 @@ ConstructCompilerInvocation(CompilerInvocation &Opts, Diagnostic &Diags,
|
|||
// options.
|
||||
InitializeCodeGenOptions(Opts.getCodeGenOpts(), *Target);
|
||||
|
||||
// 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 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize language options.
|
||||
//
|
||||
// FIXME: These aren't used during operations on ASTs. Split onto a separate
|
||||
// code path to make this obvious.
|
||||
LangKind LK = GetLanguage(Opts.getFrontendOpts().InputFilenames);
|
||||
IsAST = LK == langkind_ast;
|
||||
IsAST = (IK == FrontendOptions::IK_AST);
|
||||
if (!IsAST)
|
||||
InitializeLangOptions(Opts.getLangOpts(), LK, *Target,
|
||||
InitializeLangOptions(Opts.getLangOpts(), IK, *Target,
|
||||
Opts.getCodeGenOpts());
|
||||
|
||||
// Initialize the static analyzer options.
|
||||
|
@ -1043,7 +980,7 @@ int main(int argc, char **argv) {
|
|||
ClangFrontendTimer = new llvm::Timer("Clang front-end time");
|
||||
|
||||
if (CompOpts.getDiagnosticOpts().VerifyDiagnostics &&
|
||||
CompOpts.getFrontendOpts().InputFilenames.size() > 1) {
|
||||
CompOpts.getFrontendOpts().Inputs.size() > 1) {
|
||||
fprintf(stderr, "-verify only works on single input files.\n");
|
||||
return 1;
|
||||
}
|
||||
|
@ -1058,9 +995,9 @@ int main(int argc, char **argv) {
|
|||
// Create a file manager object to provide access to and cache the filesystem.
|
||||
FileManager FileMgr;
|
||||
|
||||
for (unsigned i = 0, e = CompOpts.getFrontendOpts().InputFilenames.size();
|
||||
for (unsigned i = 0, e = CompOpts.getFrontendOpts().Inputs.size();
|
||||
i != e; ++i) {
|
||||
const std::string &InFile = CompOpts.getFrontendOpts().InputFilenames[i];
|
||||
const std::string &InFile = CompOpts.getFrontendOpts().Inputs[i].second;
|
||||
|
||||
// AST inputs are handled specially.
|
||||
if (IsAST) {
|
||||
|
|
Loading…
Reference in New Issue