mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-03-01 14:58:18 +00:00
Add driver support for -emit-ast and AST compilation steps.
- <rdar://problem/7185031> Add 'clang' option '-emit-ast' llvm-svn: 80678
This commit is contained in:
parent
9372f4d7d5
commit
6cdf83c192
@ -43,6 +43,8 @@ def err_drv_invalid_version_number : Error<
|
||||
"invalid version number in '%0'">;
|
||||
def err_drv_no_linker_llvm_support : Error<
|
||||
"'%0': unable to pass LLVM bit-code files to linker">;
|
||||
def err_drv_no_ast_support : Error<
|
||||
"'%0': unable to use AST files with this tool">;
|
||||
def err_drv_clang_unsupported : Error<
|
||||
"the clang compiler does not support '%0'">;
|
||||
def err_drv_command_failed : Error<
|
||||
|
@ -353,6 +353,8 @@ OPTION("-dynamiclib", dynamiclib, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-dynamic", dynamic, Flag, INVALID, INVALID, "q", 0, 0, 0)
|
||||
OPTION("-d", d_Flag, Flag, d_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-d", d_Joined, Joined, d_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-emit-ast", emit_ast, Flag, INVALID, INVALID, "", 0,
|
||||
"Emit Clang AST files for source inputs", 0)
|
||||
OPTION("-emit-llvm", emit_llvm, Flag, INVALID, INVALID, "", 0,
|
||||
"Use the LLVM representation for assembler and object files", 0)
|
||||
OPTION("-exported_symbols_list", exported__symbols__list, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
|
@ -67,8 +67,9 @@ TYPE("f95-cpp-input", Fortran, PP_Fortran, 0, "u")
|
||||
TYPE("java", Java, INVALID, 0, "u")
|
||||
|
||||
// Misc.
|
||||
TYPE("llvm-asm", LLVMAsm, INVALID, "s", "")
|
||||
TYPE("llvm-bc", LLVMBC, INVALID, "o", "")
|
||||
TYPE("ast", AST, INVALID, "ast", "u")
|
||||
TYPE("llvm-asm", LLVMAsm, INVALID, "s", "")
|
||||
TYPE("llvm-bc", LLVMBC, INVALID, "o", "")
|
||||
TYPE("plist", Plist, INVALID, "plist", "")
|
||||
TYPE("precompiled-header", PCH, INVALID, "gch", "A")
|
||||
TYPE("object", Object, INVALID, "o", "")
|
||||
|
@ -345,11 +345,13 @@ void Driver::PrintHelp(bool ShowHidden) const {
|
||||
OptionHelp.push_back(std::make_pair("-ccc-gcc-name",
|
||||
"Name for native GCC compiler"));
|
||||
OptionHelp.push_back(std::make_pair("-ccc-clang-cxx",
|
||||
"Use the clang compiler for C++"));
|
||||
"Enable the clang compiler for C++"));
|
||||
OptionHelp.push_back(std::make_pair("-ccc-no-clang-cxx",
|
||||
"Disable the clang compiler for C++"));
|
||||
OptionHelp.push_back(std::make_pair("-ccc-no-clang",
|
||||
"Never use the clang compiler"));
|
||||
"Disable the clang compiler"));
|
||||
OptionHelp.push_back(std::make_pair("-ccc-no-clang-cpp",
|
||||
"Never use the clang preprocessor"));
|
||||
"Disable the clang preprocessor"));
|
||||
OptionHelp.push_back(std::make_pair("-ccc-clang-archs",
|
||||
"Comma separate list of architectures "
|
||||
"to use the clang compiler for"));
|
||||
@ -764,10 +766,11 @@ void Driver::BuildActions(const ArgList &Args, ActionList &Actions) const {
|
||||
(FinalPhaseArg = Args.getLastArg(options::OPT_MM))) {
|
||||
FinalPhase = phases::Preprocess;
|
||||
|
||||
// -{fsyntax-only,-analyze,emit-llvm,S} only run up to the compiler.
|
||||
// -{fsyntax-only,-analyze,emit-ast,S} only run up to the compiler.
|
||||
} else if ((FinalPhaseArg = Args.getLastArg(options::OPT_fsyntax_only)) ||
|
||||
(FinalPhaseArg = Args.getLastArg(options::OPT__analyze,
|
||||
options::OPT__analyze_auto)) ||
|
||||
(FinalPhaseArg = Args.getLastArg(options::OPT_emit_ast)) ||
|
||||
(FinalPhaseArg = Args.getLastArg(options::OPT_S))) {
|
||||
FinalPhase = phases::Compile;
|
||||
|
||||
@ -870,6 +873,8 @@ Action *Driver::ConstructPhaseAction(const ArgList &Args, phases::ID Phase,
|
||||
return new CompileJobAction(Input, types::TY_Nothing);
|
||||
} else if (Args.hasArg(options::OPT__analyze, options::OPT__analyze_auto)) {
|
||||
return new AnalyzeJobAction(Input, types::TY_Plist);
|
||||
} else if (Args.hasArg(options::OPT_emit_ast)) {
|
||||
return new CompileJobAction(Input, types::TY_AST);
|
||||
} else if (Args.hasArg(options::OPT_emit_llvm) ||
|
||||
Args.hasArg(options::OPT_flto) ||
|
||||
Args.hasArg(options::OPT_O4)) {
|
||||
@ -1275,7 +1280,7 @@ bool Driver::ShouldUseClangCompiler(const Compilation &C, const JobAction &JA,
|
||||
|
||||
// Check if user requested no clang, or clang doesn't understand
|
||||
// this type (we only handle single inputs for now).
|
||||
if (!CCCUseClang || JA.size() != 1 ||
|
||||
if (!CCCUseClang || JA.size() != 1 ||
|
||||
!types::isAcceptedByClang((*JA.begin())->getType()))
|
||||
return false;
|
||||
|
||||
@ -1294,10 +1299,9 @@ bool Driver::ShouldUseClangCompiler(const Compilation &C, const JobAction &JA,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Always use clang for precompiling, regardless of archs. PTH is
|
||||
// platform independent, and this allows the use of the static
|
||||
// analyzer on platforms we don't have full IRgen support for.
|
||||
if (isa<PrecompileJobAction>(JA))
|
||||
// Always use clang for precompiling and AST generation, regardless of
|
||||
// archs.
|
||||
if (isa<PrecompileJobAction>(JA) || JA.getType() == types::TY_AST)
|
||||
return true;
|
||||
|
||||
// Finally, don't use clang if this isn't one of the user specified
|
||||
|
@ -220,7 +220,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
} else if (JA.getType() == types::TY_LLVMBC) {
|
||||
CmdArgs.push_back("-emit-llvm-bc");
|
||||
} else if (JA.getType() == types::TY_PP_Asm) {
|
||||
CmdArgs.push_back("-S");
|
||||
if (Inputs[0].getType() == types::TY_AST)
|
||||
CmdArgs.push_back("-compile-ast");
|
||||
else
|
||||
CmdArgs.push_back("-S");
|
||||
} else if (JA.getType() == types::TY_AST) {
|
||||
CmdArgs.push_back("-emit-pch");
|
||||
}
|
||||
}
|
||||
|
||||
@ -768,10 +773,13 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
|
||||
const InputInfo &II = *it;
|
||||
|
||||
// Don't try to pass LLVM inputs to a generic gcc.
|
||||
// Don't try to pass LLVM or AST inputs to a generic gcc.
|
||||
if (II.getType() == types::TY_LLVMBC)
|
||||
D.Diag(clang::diag::err_drv_no_linker_llvm_support)
|
||||
<< getToolChain().getTripleString().c_str();
|
||||
else if (II.getType() == types::TY_AST)
|
||||
D.Diag(clang::diag::err_drv_no_ast_support)
|
||||
<< getToolChain().getTripleString().c_str();
|
||||
|
||||
if (types::canTypeBeUserSpecified(II.getType())) {
|
||||
CmdArgs.push_back("-x");
|
||||
@ -1189,6 +1197,9 @@ void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
CmdArgs.push_back("-emit-llvm");
|
||||
else if (Output.getType() == types::TY_LLVMBC)
|
||||
CmdArgs.push_back("-emit-llvm-bc");
|
||||
else if (Output.getType() == types::TY_AST)
|
||||
D.Diag(clang::diag::err_drv_no_ast_support)
|
||||
<< getToolChain().getTripleString().c_str();
|
||||
|
||||
ArgStringList OutputArgs;
|
||||
if (Output.getType() != types::TY_PCH) {
|
||||
@ -1224,6 +1235,13 @@ void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
|
||||
const InputInfo &II = *it;
|
||||
|
||||
// Reject AST inputs.
|
||||
if (II.getType() == types::TY_AST) {
|
||||
D.Diag(clang::diag::err_drv_no_ast_support)
|
||||
<< getToolChain().getTripleString().c_str();
|
||||
return;
|
||||
}
|
||||
|
||||
if (II.isPipe())
|
||||
CmdArgs.push_back("-");
|
||||
else
|
||||
|
@ -83,6 +83,7 @@ bool types::isAcceptedByClang(ID Id) {
|
||||
case TY_ObjCHeader: case TY_PP_ObjCHeader:
|
||||
case TY_CXXHeader: case TY_PP_CXXHeader:
|
||||
case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
|
||||
case TY_AST:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -128,6 +129,7 @@ types::ID types::lookupTypeForExtension(const char *Ext) {
|
||||
case 3:
|
||||
if (memcmp(Ext, "ads", 3) == 0) return TY_Ada;
|
||||
if (memcmp(Ext, "adb", 3) == 0) return TY_Ada;
|
||||
if (memcmp(Ext, "ast", 3) == 0) return TY_AST;
|
||||
if (memcmp(Ext, "cxx", 3) == 0) return TY_CXX;
|
||||
if (memcmp(Ext, "cpp", 3) == 0) return TY_CXX;
|
||||
if (memcmp(Ext, "CPP", 3) == 0) return TY_CXX;
|
||||
|
22
clang/test/Driver/ast.c
Normal file
22
clang/test/Driver/ast.c
Normal file
@ -0,0 +1,22 @@
|
||||
// RUN: clang -ccc-host-triple i386-unknown-unknown -ccc-print-phases -emit-ast %s 2> %t &&
|
||||
// RUN: FileCheck -check-prefix EMIT-AST-PHASES -input-file %t %s &&
|
||||
|
||||
// EMIT-AST-PHASES: 0: input,
|
||||
// EMIT-AST-PHASES: , c
|
||||
// EMIT-AST-PHASES: 1: preprocessor, {0}, cpp-output
|
||||
// EMIT-AST-PHASES: 2: compiler, {1}, ast
|
||||
// EMIT-AST-PHASES-NOT: 3:
|
||||
|
||||
// RUN: touch %t.ast &&
|
||||
// RUN: clang -ccc-host-triple i386-unknown-unknown -ccc-print-phases -c %t.ast 2> %t &&
|
||||
// RUN: FileCheck -check-prefix COMPILE-AST-PHASES -input-file %t %s
|
||||
|
||||
// COMPILE-AST-PHASES: 0: input,
|
||||
// COMPILE-AST-PHASES: , ast
|
||||
// COMPILE-AST-PHASES: 1: compiler, {0}, assembler
|
||||
// COMPILE-AST-PHASES: 2: assembler, {1}, object
|
||||
// COMPILE-AST-PHASES-NOT: 3:
|
||||
|
||||
// FIXME: There is a problem with compiling AST's in that the input language is
|
||||
// not availabe for use by other tools (for example, to automatically add
|
||||
// -lstdc++). We may need -x [objective-]c++-ast and all that goodness. :(
|
Loading…
x
Reference in New Issue
Block a user