diff options
-rw-r--r-- | include/clang/Driver/CC1Options.td | 2 | ||||
-rw-r--r-- | include/clang/Lex/PreprocessorOptions.h | 3 | ||||
-rw-r--r-- | lib/Driver/ToolChains/Clang.cpp | 4 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 2 | ||||
-rw-r--r-- | lib/Frontend/InitPreprocessor.cpp | 9 | ||||
-rw-r--r-- | test/Analysis/preprocessor-setup.c | 5 | ||||
-rw-r--r-- | test/ClangScanDeps/Inputs/static-analyzer-cdb.json | 7 | ||||
-rw-r--r-- | test/ClangScanDeps/static-analyzer.c | 16 |
8 files changed, 44 insertions, 4 deletions
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 66906fb862..e0974fbb5a 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -846,6 +846,8 @@ def preamble_bytes_EQ : Joined<["-"], "preamble-bytes=">, "covering the first N bytes of the main file">; def detailed_preprocessing_record : Flag<["-"], "detailed-preprocessing-record">, HelpText<"include a detailed record of preprocessing actions">; +def setup_static_analyzer : Flag<["-"], "setup-static-analyzer">, + HelpText<"Set up preprocessor for static analyzer (done automatically when static analyzer is run).">; //===----------------------------------------------------------------------===// // OpenCL Options diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h index aa62b9bb48..344afa8941 100644 --- a/include/clang/Lex/PreprocessorOptions.h +++ b/include/clang/Lex/PreprocessorOptions.h @@ -181,6 +181,9 @@ public: ExcludedPreprocessorDirectiveSkipMapping *ExcludedConditionalDirectiveSkipMappings = nullptr; + /// Set up preprocessor for RunAnalysis action. + bool SetUpStaticAnalyzer = false; + public: PreprocessorOptions() : PrecompiledPreambleBytes(0, false) {} diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index e35408876b..52fe20c3a9 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -3803,6 +3803,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (isa<AnalyzeJobAction>(JA)) RenderAnalyzerOptions(Args, CmdArgs, Triple, Input); + if (isa<AnalyzeJobAction>(JA) || + (isa<PreprocessJobAction>(JA) && Args.hasArg(options::OPT__analyze))) + CmdArgs.push_back("-setup-static-analyzer"); + // Enable compatilibily mode to avoid analyzer-config related errors. // Since we can't access frontend flags through hasArg, let's manually iterate // through them. diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 3c0fc391ea..9d5987f07f 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -3349,6 +3349,8 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, // "editor placeholder in source file" error in PP only mode. if (isStrictlyPreprocessorAction(Action)) Opts.LexEditorPlaceholders = false; + + Opts.SetUpStaticAnalyzer = Args.hasArg(OPT_setup_static_analyzer); } static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp index 6810379c6f..3715dcfda4 100644 --- a/lib/Frontend/InitPreprocessor.cpp +++ b/lib/Frontend/InitPreprocessor.cpp @@ -560,6 +560,7 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, static void InitializePredefinedMacros(const TargetInfo &TI, const LangOptions &LangOpts, const FrontendOptions &FEOpts, + const PreprocessorOptions &PPOpts, MacroBuilder &Builder) { // Compiler version introspection macros. Builder.defineMacro("__llvm__"); // LLVM Backend @@ -997,8 +998,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, else if (LangOpts.getStackProtector() == LangOptions::SSPReq) Builder.defineMacro("__SSP_ALL__", "3"); - // Define a macro that exists only when using the static analyzer. - if (FEOpts.ProgramAction == frontend::RunAnalysis) + if (PPOpts.SetUpStaticAnalyzer) Builder.defineMacro("__clang_analyzer__"); if (LangOpts.FastRelaxedMath) @@ -1125,9 +1125,10 @@ void clang::InitializePreprocessor( // macros. This is not the right way to handle this. if ((LangOpts.CUDA || LangOpts.OpenMPIsDevice) && PP.getAuxTargetInfo()) InitializePredefinedMacros(*PP.getAuxTargetInfo(), LangOpts, FEOpts, - Builder); + PP.getPreprocessorOpts(), Builder); - InitializePredefinedMacros(PP.getTargetInfo(), LangOpts, FEOpts, Builder); + InitializePredefinedMacros(PP.getTargetInfo(), LangOpts, FEOpts, + PP.getPreprocessorOpts(), Builder); // Install definitions to make Objective-C++ ARC work well with various // C++ Standard Library implementations. diff --git a/test/Analysis/preprocessor-setup.c b/test/Analysis/preprocessor-setup.c new file mode 100644 index 0000000000..57f13e6e7d --- /dev/null +++ b/test/Analysis/preprocessor-setup.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -E -setup-static-analyzer %s + +#ifndef __clang_analyzer__ +#error __clang_analyzer__ not defined +#endif diff --git a/test/ClangScanDeps/Inputs/static-analyzer-cdb.json b/test/ClangScanDeps/Inputs/static-analyzer-cdb.json new file mode 100644 index 0000000000..a466d87afa --- /dev/null +++ b/test/ClangScanDeps/Inputs/static-analyzer-cdb.json @@ -0,0 +1,7 @@ +[ +{ + "directory": "DIR", + "command": "clang --analyze DIR/static-analyzer.c", + "file": "DIR/static-analyzer.c" +} +] diff --git a/test/ClangScanDeps/static-analyzer.c b/test/ClangScanDeps/static-analyzer.c new file mode 100644 index 0000000000..dca35039d8 --- /dev/null +++ b/test/ClangScanDeps/static-analyzer.c @@ -0,0 +1,16 @@ +// RUN: rm -rf %t.dir +// RUN: rm -rf %t.dir/cdb.json +// RUN: mkdir -p %t.dir +// RUN: cp %s %t.dir/static-analyzer.c +// RUN: mkdir %t.dir/Inputs +// RUN: cp %S/Inputs/header.h %t.dir/Inputs/analyze_header_input.h +// RUN: sed -e "s|DIR|%t.dir|g" %S/Inputs/static-analyzer-cdb.json > %t.dir/cdb.json +// +// RUN: clang-scan-deps -compilation-database %t.dir/cdb.json -j 1 | FileCheck %s + +#ifdef __clang_analyzer__ +#include "Inputs/analyze_header_input.h" +#endif + +// CHECK: analyze_header_input.h + |