forked from OSchip/llvm-project
ccc: Add --analyze driver mode (for running static analyzer).
- For now forces generation of plist files, need to think about the right interface. - Changed -fsyntax-only mode to be its own phase (more consistent). - Add -WA, for passing options verbatim to analyzer. llvm-svn: 62649
This commit is contained in:
parent
13747167ca
commit
989ab477d2
|
@ -527,6 +527,8 @@ class OptionParser:
|
|||
|
||||
# Blanket pass-through options.
|
||||
|
||||
self.WAOption = self.addOption(CommaJoinedOption('-WA,'))
|
||||
|
||||
self.WaOption = self.addOption(CommaJoinedOption('-Wa,'))
|
||||
self.XassemblerOption = self.addOption(SeparateOption('-Xassembler'))
|
||||
|
||||
|
@ -831,6 +833,9 @@ class OptionParser:
|
|||
self.addOption(JoinedOrSeparateOption('-V'))
|
||||
self.addOption(JoinedOrSeparateOption('-b'))
|
||||
|
||||
# Clang static analyzer options (also see -WA,).
|
||||
self.analyzeOption = self.addOption(FlagOption('--analyze'))
|
||||
|
||||
def addOption(self, opt):
|
||||
self.options.append(opt)
|
||||
return opt
|
||||
|
|
|
@ -333,6 +333,7 @@ class Driver(object):
|
|||
sys.exit(1)
|
||||
|
||||
def buildNormalPipeline(self, args):
|
||||
hasAnalyze = args.getLastArg(self.parser.analyzeOption)
|
||||
hasCombine = args.getLastArg(self.parser.combineOption)
|
||||
hasSyntaxOnly = args.getLastArg(self.parser.syntaxOnlyOption)
|
||||
hasDashC = args.getLastArg(self.parser.cOption)
|
||||
|
@ -406,6 +407,9 @@ class Driver(object):
|
|||
if hasDashE or hasDashM or hasDashMM:
|
||||
finalPhase = Phases.Phase.eOrderPreprocess
|
||||
finalPhaseOpt = hasDashE
|
||||
elif hasAnalyze:
|
||||
finalPhase = Phases.Phase.eOrderCompile
|
||||
finalPhaseOpt = hasAnalyze
|
||||
elif hasSyntaxOnly:
|
||||
finalPhase = Phases.Phase.eOrderCompile
|
||||
finalPhaseOpt = hasSyntaxOnly
|
||||
|
@ -455,6 +459,10 @@ class Driver(object):
|
|||
linkPhase])
|
||||
elif klass.onlyPrecompile:
|
||||
sequence.append(Phases.PrecompilePhase())
|
||||
elif hasAnalyze:
|
||||
sequence.append(Phases.AnalyzePhase())
|
||||
elif hasSyntaxOnly:
|
||||
sequence.append(Phases.SyntaxOnlyPhase())
|
||||
else:
|
||||
sequence.extend([Phases.CompilePhase(),
|
||||
Phases.AssemblePhase(),
|
||||
|
@ -487,11 +495,18 @@ class Driver(object):
|
|||
current = Phases.JobAction(transition,
|
||||
[current],
|
||||
Types.PCHType)
|
||||
elif isinstance(transition, Phases.AnalyzePhase):
|
||||
output = Types.PlistType
|
||||
current = Phases.JobAction(transition,
|
||||
[current],
|
||||
output)
|
||||
elif isinstance(transition, Phases.SyntaxOnlyPhase):
|
||||
output = Types.NothingType
|
||||
current = Phases.JobAction(transition,
|
||||
[current],
|
||||
output)
|
||||
elif isinstance(transition, Phases.CompilePhase):
|
||||
if hasSyntaxOnly:
|
||||
output = Types.NothingType
|
||||
else:
|
||||
output = Types.AsmTypeNoPP
|
||||
output = Types.AsmTypeNoPP
|
||||
current = Phases.JobAction(transition,
|
||||
[current],
|
||||
output)
|
||||
|
|
|
@ -68,6 +68,14 @@ class PrecompilePhase(Phase):
|
|||
def __init__(self):
|
||||
super(PrecompilePhase, self).__init__("precompiler", Phase.eOrderCompile)
|
||||
|
||||
class AnalyzePhase(Phase):
|
||||
def __init__(self):
|
||||
super(AnalyzePhase, self).__init__("analyze", Phase.eOrderCompile)
|
||||
|
||||
class SyntaxOnlyPhase(Phase):
|
||||
def __init__(self):
|
||||
super(SyntaxOnlyPhase, self).__init__("syntax-only", Phase.eOrderCompile)
|
||||
|
||||
class CompilePhase(Phase):
|
||||
def __init__(self):
|
||||
super(CompilePhase, self).__init__("compiler", Phase.eOrderCompile)
|
||||
|
|
|
@ -51,15 +51,17 @@ class Darwin_X86_ToolChain(ToolChain):
|
|||
self.gccVersion = gccVersion
|
||||
self.archName = archName
|
||||
|
||||
self.clangTool = Tools.Clang_CompileTool(self)
|
||||
self.toolMap = {
|
||||
Phases.PreprocessPhase : Tools.Darwin_X86_PreprocessTool(self),
|
||||
Phases.AnalyzePhase : self.clangTool,
|
||||
Phases.SyntaxOnlyPhase : Tools.Darwin_X86_CompileTool(self),
|
||||
Phases.CompilePhase : Tools.Darwin_X86_CompileTool(self),
|
||||
Phases.PrecompilePhase : Tools.Darwin_X86_CompileTool(self),
|
||||
Phases.AssemblePhase : Tools.Darwin_AssembleTool(self),
|
||||
Phases.LinkPhase : Tools.Darwin_X86_LinkTool(self),
|
||||
Phases.LipoPhase : Tools.LipoTool(),
|
||||
}
|
||||
self.clangTool = Tools.Clang_CompileTool()
|
||||
|
||||
def getToolChainDir(self):
|
||||
return 'i686-apple-darwin%d/%s' % (self.darwinVersion[0],
|
||||
|
@ -171,6 +173,8 @@ class Generic_GCC_ToolChain(ToolChain):
|
|||
super(Generic_GCC_ToolChain, self).__init__(driver)
|
||||
self.toolMap = {
|
||||
Phases.PreprocessPhase : Tools.GCC_PreprocessTool(),
|
||||
Phases.AnalyzePhase : Tools.Clang_CompileTool(self),
|
||||
Phases.SyntaxOnlyPhase : Tools.GCC_CompileTool(),
|
||||
Phases.CompilePhase : Tools.GCC_CompileTool(),
|
||||
Phases.PrecompilePhase : Tools.GCC_PrecompileTool(),
|
||||
Phases.AssemblePhase : Tools.GCC_AssembleTool(),
|
||||
|
|
|
@ -3,6 +3,7 @@ import sys # FIXME: Shouldn't be needed.
|
|||
|
||||
import Arguments
|
||||
import Jobs
|
||||
import Phases
|
||||
import Types
|
||||
|
||||
class Tool(object):
|
||||
|
@ -39,9 +40,10 @@ class GCC_Common_Tool(Tool):
|
|||
cmd_args.extend(arglist.render(arch))
|
||||
if isinstance(output, Jobs.PipedJob):
|
||||
cmd_args.extend(['-o', '-'])
|
||||
elif output is None:
|
||||
elif isinstance(phase.phase, Phases.SyntaxOnlyPhase):
|
||||
cmd_args.append('-fsyntax-only')
|
||||
else:
|
||||
assert output
|
||||
cmd_args.extend(arglist.render(output))
|
||||
|
||||
if (isinstance(self, GCC_LinkTool) and
|
||||
|
@ -163,18 +165,22 @@ class Darwin_AssembleTool(Tool):
|
|||
cmd_args))
|
||||
|
||||
class Clang_CompileTool(Tool):
|
||||
def __init__(self):
|
||||
def __init__(self, toolChain):
|
||||
super(Clang_CompileTool, self).__init__('clang',
|
||||
(Tool.eFlagsPipedInput |
|
||||
Tool.eFlagsPipedOutput |
|
||||
Tool.eFlagsIntegratedCPP))
|
||||
self.toolChain = toolChain
|
||||
|
||||
def constructJob(self, phase, arch, jobs, inputs,
|
||||
output, outputType, arglist, linkingOutput):
|
||||
cmd_args = []
|
||||
|
||||
patchOutputNameForPTH = False
|
||||
if output is None:
|
||||
|
||||
if isinstance(phase.phase, Phases.AnalyzePhase):
|
||||
cmd_args.append('-analyze')
|
||||
elif isinstance(phase.phase, Phases.SyntaxOnlyPhase):
|
||||
cmd_args.append('-fsyntax-only')
|
||||
elif outputType is Types.AsmTypeNoPP:
|
||||
cmd_args.append('-S')
|
||||
|
@ -198,6 +204,22 @@ class Clang_CompileTool(Tool):
|
|||
else:
|
||||
raise ValueError,"Unexpected output type for clang tool."
|
||||
|
||||
if isinstance(phase.phase, Phases.AnalyzePhase):
|
||||
# Add default argument set.
|
||||
#
|
||||
# FIXME: Move into clang?
|
||||
cmd_args.extend(['-warn-dead-stores',
|
||||
'-checker-cfref',
|
||||
'-warn-objc-methodsigs',
|
||||
'-warn-objc-missing-dealloc',
|
||||
'-warn-objc-unused-ivars'])
|
||||
|
||||
cmd_args.append('-analyzer-output-plist')
|
||||
|
||||
# Add -WA, arguments when running as analyzer.
|
||||
for arg in arglist.getArgs(arglist.parser.WAOption):
|
||||
cmd_args.extend(arglist.renderAsInput(arg))
|
||||
|
||||
arglist.addAllArgs(cmd_args, arglist.parser.vOption)
|
||||
arglist.addAllArgs2(cmd_args, arglist.parser.DOption, arglist.parser.UOption)
|
||||
arglist.addAllArgs2(cmd_args, arglist.parser.IOption, arglist.parser.FOption)
|
||||
|
@ -252,7 +274,7 @@ class Clang_CompileTool(Tool):
|
|||
suffix = '.pth'
|
||||
cmd_args.append('-o')
|
||||
cmd_args.append(base + suffix)
|
||||
else:
|
||||
elif output:
|
||||
cmd_args.extend(arglist.render(output))
|
||||
|
||||
for input in inputs:
|
||||
|
|
|
@ -69,6 +69,7 @@ FortranType = InputType('f95-cpp-input', FortranTypeNoPP, canBeUserSpecified=Tru
|
|||
JavaType = InputType('java', canBeUserSpecified=True)
|
||||
|
||||
# Misc.
|
||||
PlistType = InputType('plist', tempSuffix='plist')
|
||||
PCHType = InputType('precompiled-header', tempSuffix='gch')
|
||||
ObjectType = InputType('object', tempSuffix='o')
|
||||
TreelangType = InputType('treelang', canBeUserSpecified=True)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
__all__ = []
|
|
@ -30,7 +30,7 @@
|
|||
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -E %s > %t &&
|
||||
// RUN: not grep ': compiler, ' %t &&
|
||||
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -fsyntax-only %s > %t &&
|
||||
// RUN: grep ': compiler, {1}, nothing' %t &&
|
||||
// RUN: grep ': syntax-only, {1}, nothing' %t &&
|
||||
// RUN: not grep ': assembler, ' %t &&
|
||||
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -S %s > %t &&
|
||||
// RUN: not grep ': assembler, ' %t &&
|
||||
|
|
Loading…
Reference in New Issue