]> granicus.if.org Git - clang/commitdiff
ccc: Add --analyze driver mode (for running static analyzer).
authorDaniel Dunbar <daniel@zuster.org>
Wed, 21 Jan 2009 01:07:49 +0000 (01:07 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Wed, 21 Jan 2009 01:07:49 +0000 (01:07 +0000)
 - 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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62649 91177308-0d34-0410-b5e6-96231b3b80d8

tools/ccc/ccclib/Arguments.py
tools/ccc/ccclib/Driver.py
tools/ccc/ccclib/Phases.py
tools/ccc/ccclib/ToolChain.py
tools/ccc/ccclib/Tools.py
tools/ccc/ccclib/Types.py
tools/ccc/ccclib/__init__.py
tools/ccc/test/ccc/phases.c

index 04dfbbf1e21ec27cd030da66f0a23418b80f59d8..d9fd11d389729440a5b77cfd293ebf70de337682 100644 (file)
@@ -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
index 65b53166a7f64d3197ffc110d8d54f2615e47262..de4596bf2c0df3d343f7121ae312ca1fc61f3a57 100644 (file)
@@ -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)
index 0384b8fa4fc9716607aad22fb3fd221fe163e387..160e72c06eb1064453e34bc5d050b31456b80cd2 100644 (file)
@@ -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)
index ac1cc0a0badae08f4fc23212418f2009a459ab20..ee244d7ec0bc4b3668cc12b5ba3792b651e3af27 100644 (file)
@@ -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(),
index 2bb694c4e284545e2fe29b0213ddd2a541fa1695..11a6047182a04e7bf3b4fd351381be93d3b3c479 100644 (file)
@@ -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:
index 19c1f5fffbdd830c5ed2d10ae5453e37a55432cf..c04e61d91d84101ca69d175f5b53a1c4f1253831 100644 (file)
@@ -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)
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a9a2c5b3bb437bff74e283b62c894075e8c15331 100644 (file)
@@ -0,0 +1 @@
+__all__ = []
index 902ceb429882e056c0381349fbddb9297418e1a4..2f4571a769dd885303ffde75d23d2d23034b0318 100644 (file)
@@ -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 &&