 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
51.9% |
40 / 77 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
74.0% |
57 / 77 |
| |
|
Line Coverage: |
44.0% |
55 / 125 |
| |
 |
|
 |
1 : //===-- cc1_main.cpp - Clang CC1 Driver -----------------------------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This is the entry point to the clang -cc1 functionality, which implements the
11 : // core compiler functionality along with a number of additional tools for
12 : // demonstration and testing purposes.
13 : //
14 : //===----------------------------------------------------------------------===//
15 :
16 : #include "clang/Basic/Diagnostic.h"
17 : #include "clang/Driver/Arg.h"
18 : #include "clang/Driver/ArgList.h"
19 : #include "clang/Driver/CC1Options.h"
20 : #include "clang/Driver/DriverDiagnostic.h"
21 : #include "clang/Driver/OptTable.h"
22 : #include "clang/Frontend/CompilerInstance.h"
23 : #include "clang/Frontend/CompilerInvocation.h"
24 : #include "clang/Frontend/FrontendActions.h"
25 : #include "clang/Frontend/FrontendDiagnostic.h"
26 : #include "clang/Frontend/FrontendPluginRegistry.h"
27 : #include "clang/Frontend/TextDiagnosticBuffer.h"
28 : #include "clang/Frontend/TextDiagnosticPrinter.h"
29 : #include "llvm/LLVMContext.h"
30 : #include "llvm/ADT/OwningPtr.h"
31 : #include "llvm/Support/ErrorHandling.h"
32 : #include "llvm/Support/ManagedStatic.h"
33 : #include "llvm/Support/PrettyStackTrace.h"
34 : #include "llvm/Support/raw_ostream.h"
35 : #include "llvm/System/DynamicLibrary.h"
36 : #include "llvm/System/Signals.h"
37 : #include "llvm/Target/TargetSelect.h"
38 : #include <cstdio>
39 : using namespace clang;
40 :
41 : //===----------------------------------------------------------------------===//
42 : // Main driver
43 : //===----------------------------------------------------------------------===//
44 :
45 0: void LLVMErrorHandler(void *UserData, const std::string &Message) {
46 0: Diagnostic &Diags = *static_cast<Diagnostic*>(UserData);
47 :
48 0: Diags.Report(diag::err_fe_error_backend) << Message;
49 :
50 : // We cannot recover from llvm errors.
51 0: exit(1);
52 : }
53 :
54 2513: static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) {
55 : using namespace clang::frontend;
56 :
0: branch 1 not taken
5: branch 2 taken
17: branch 3 taken
1: branch 4 taken
0: branch 5 not taken
0: branch 6 not taken
1: branch 7 taken
3: branch 8 taken
57: branch 9 taken
18: branch 10 taken
3: branch 11 taken
516: branch 12 taken
35: branch 13 taken
0: branch 14 not taken
12: branch 15 taken
44: branch 16 taken
1: branch 17 taken
0: branch 18 not taken
13: branch 19 taken
2: branch 20 taken
1280: branch 21 taken
0: branch 22 not taken
2: branch 23 taken
245: branch 24 taken
1: branch 25 taken
51: branch 26 taken
0: branch 27 not taken
188: branch 28 taken
18: branch 29 taken
57 2513: switch (CI.getFrontendOpts().ProgramAction) {
58 : default:
59 0: llvm_unreachable("Invalid program action!");
60 :
61 5: case ASTDump: return new ASTDumpAction();
62 17: case ASTPrint: return new ASTPrintAction();
63 1: case ASTPrintXML: return new ASTPrintXMLAction();
64 0: case ASTView: return new ASTViewAction();
65 0: case DumpRawTokens: return new DumpRawTokensAction();
66 1: case DumpRecordLayouts: return new DumpRecordAction();
67 3: case DumpTokens: return new DumpTokensAction();
68 57: case EmitAssembly: return new EmitAssemblyAction();
69 18: case EmitBC: return new EmitBCAction();
70 3: case EmitHTML: return new HTMLPrintAction();
71 516: case EmitLLVM: return new EmitLLVMAction();
72 35: case EmitLLVMOnly: return new EmitLLVMOnlyAction();
73 0: case EmitObj: return new EmitObjAction();
74 12: case FixIt: return new FixItAction();
75 44: case GeneratePCH: return new GeneratePCHAction();
76 1: case GeneratePTH: return new GeneratePTHAction();
77 0: case InheritanceView: return new InheritanceViewAction();
78 13: case ParseNoop: return new ParseOnlyAction();
79 2: case ParsePrintCallbacks: return new PrintParseAction();
80 1280: case ParseSyntaxOnly: return new SyntaxOnlyAction();
81 :
82 : case PluginAction: {
0: branch 2 not taken
0: branch 3 not taken
83 0: if (CI.getFrontendOpts().ActionName == "help") {
84 0: llvm::errs() << "clang -cc1 plugins:\n";
0: branch 2 not taken
0: branch 3 not taken
85 0: for (FrontendPluginRegistry::iterator it =
86 0: FrontendPluginRegistry::begin(),
87 0: ie = FrontendPluginRegistry::end();
88 : it != ie; ++it)
89 0: llvm::errs() << " " << it->getName() << " - " << it->getDesc() << "\n";
90 0: return 0;
91 : }
92 :
0: branch 2 not taken
0: branch 3 not taken
93 0: for (FrontendPluginRegistry::iterator it =
94 0: FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end();
95 : it != ie; ++it) {
0: branch 4 not taken
0: branch 5 not taken
96 0: if (it->getName() == CI.getFrontendOpts().ActionName)
97 0: return it->instantiate();
98 : }
99 :
100 : CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
101 0: << CI.getFrontendOpts().ActionName;
102 0: return 0;
103 : }
104 :
105 2: case PrintDeclContext: return new DeclContextPrintAction();
106 245: case PrintPreprocessedInput: return new PrintPreprocessedAction();
107 1: case RewriteMacros: return new RewriteMacrosAction();
108 51: case RewriteObjC: return new RewriteObjCAction();
109 0: case RewriteTest: return new RewriteTestAction();
110 188: case RunAnalysis: return new AnalysisAction();
111 18: case RunPreprocessorOnly: return new PreprocessOnlyAction();
112 : }
113 : }
114 :
115 2513: static FrontendAction *CreateFrontendAction(CompilerInstance &CI) {
116 : // Create the underlying action.
117 2513: FrontendAction *Act = CreateFrontendBaseAction(CI);
0: branch 0 not taken
2513: branch 1 taken
118 2513: if (!Act)
119 0: return 0;
120 :
121 : // If there are any AST files to merge, create a frontend action
122 : // adaptor to perform the merge.
1: branch 2 taken
2512: branch 3 taken
123 2513: if (!CI.getFrontendOpts().ASTMergeFiles.empty())
124 : Act = new ASTMergeAction(Act, &CI.getFrontendOpts().ASTMergeFiles[0],
125 1: CI.getFrontendOpts().ASTMergeFiles.size());
126 :
127 2513: return Act;
128 : }
129 :
130 : // FIXME: Define the need for this testing away.
131 : static int cc1_test(Diagnostic &Diags,
132 0: const char **ArgBegin, const char **ArgEnd) {
133 : using namespace clang::driver;
134 :
135 0: llvm::errs() << "cc1 argv:";
0: branch 0 not taken
0: branch 1 not taken
136 0: for (const char **i = ArgBegin; i != ArgEnd; ++i)
137 0: llvm::errs() << " \"" << *i << '"';
138 0: llvm::errs() << "\n";
139 :
140 : // Parse the arguments.
141 0: OptTable *Opts = createCC1OptTable();
142 : unsigned MissingArgIndex, MissingArgCount;
143 : InputArgList *Args = Opts->ParseArgs(ArgBegin, ArgEnd,
144 0: MissingArgIndex, MissingArgCount);
145 :
146 : // Check for missing argument error.
0: branch 0 not taken
0: branch 1 not taken
147 0: if (MissingArgCount)
148 : Diags.Report(clang::diag::err_drv_missing_argument)
149 0: << Args->getArgString(MissingArgIndex) << MissingArgCount;
150 :
151 : // Dump the parsed arguments.
152 0: llvm::errs() << "cc1 parsed options:\n";
0: branch 2 not taken
0: branch 3 not taken
153 0: for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
154 : it != ie; ++it)
155 0: (*it)->dump();
156 :
157 : // Create a compiler invocation.
158 0: llvm::errs() << "cc1 creating invocation.\n";
159 0: CompilerInvocation Invocation;
160 0: CompilerInvocation::CreateFromArgs(Invocation, ArgBegin, ArgEnd, Diags);
161 :
162 : // Convert the invocation back to argument strings.
163 0: std::vector<std::string> InvocationArgs;
164 0: Invocation.toArgs(InvocationArgs);
165 :
166 : // Dump the converted arguments.
167 0: llvm::SmallVector<const char*, 32> Invocation2Args;
168 0: llvm::errs() << "invocation argv :";
0: branch 1 not taken
0: branch 2 not taken
169 0: for (unsigned i = 0, e = InvocationArgs.size(); i != e; ++i) {
170 0: Invocation2Args.push_back(InvocationArgs[i].c_str());
171 0: llvm::errs() << " \"" << InvocationArgs[i] << '"';
172 : }
173 0: llvm::errs() << "\n";
174 :
175 : // Convert those arguments to another invocation, and check that we got the
176 : // same thing.
177 0: CompilerInvocation Invocation2;
178 : CompilerInvocation::CreateFromArgs(Invocation2, Invocation2Args.begin(),
179 0: Invocation2Args.end(), Diags);
180 :
181 : // FIXME: Implement CompilerInvocation comparison.
182 0: if (true) {
183 : //llvm::errs() << "warning: Invocations differ!\n";
184 :
185 0: std::vector<std::string> Invocation2Args;
186 0: Invocation2.toArgs(Invocation2Args);
187 0: llvm::errs() << "invocation2 argv:";
0: branch 1 not taken
0: branch 2 not taken
188 0: for (unsigned i = 0, e = Invocation2Args.size(); i != e; ++i)
189 0: llvm::errs() << " \"" << Invocation2Args[i] << '"';
190 0: llvm::errs() << "\n";
191 : }
192 :
193 0: return 0;
194 : }
195 :
196 : int cc1_main(const char **ArgBegin, const char **ArgEnd,
197 2514: const char *Argv0, void *MainAddr) {
198 2514: CompilerInstance Clang(&llvm::getGlobalContext(), false);
199 :
200 : // Run clang -cc1 test.
2514: branch 0 taken
0: branch 1 not taken
0: branch 5 not taken
2514: branch 6 taken
0: branch 7 not taken
2514: branch 8 taken
201 2514: if (ArgBegin != ArgEnd && llvm::StringRef(ArgBegin[0]) == "-cc1test") {
202 0: TextDiagnosticPrinter DiagClient(llvm::errs(), DiagnosticOptions());
203 0: Diagnostic Diags(&DiagClient);
204 0: return cc1_test(Diags, ArgBegin + 1, ArgEnd);
205 : }
206 :
207 : // Initialize targets first, so that --version shows registered targets.
208 2514: llvm::InitializeAllTargets();
209 2514: llvm::InitializeAllAsmPrinters();
210 :
211 : // Buffer diagnostics from argument parsing so that we can output them using a
212 : // well formed diagnostic object.
213 2514: TextDiagnosticBuffer DiagsBuffer;
214 2514: Diagnostic Diags(&DiagsBuffer);
215 : CompilerInvocation::CreateFromArgs(Clang.getInvocation(), ArgBegin, ArgEnd,
216 2514: Diags);
217 :
218 : // Infer the builtin include path if unspecified.
2514: branch 1 taken
0: branch 2 not taken
2372: branch 5 taken
142: branch 6 taken
2372: branch 7 taken
142: branch 8 taken
219 2514: if (Clang.getHeaderSearchOpts().UseBuiltinIncludes &&
220 : Clang.getHeaderSearchOpts().ResourceDir.empty())
221 : Clang.getHeaderSearchOpts().ResourceDir =
222 2372: CompilerInvocation::GetResourcesPath(Argv0, MainAddr);
223 :
224 : // Honor -help.
0: branch 1 not taken
2514: branch 2 taken
225 2514: if (Clang.getFrontendOpts().ShowHelp) {
226 0: llvm::OwningPtr<driver::OptTable> Opts(driver::createCC1OptTable());
227 : Opts->PrintHelp(llvm::outs(), "clang -cc1",
228 0: "LLVM 'Clang' Compiler: http://clang.llvm.org");
229 0: return 0;
230 : }
231 :
232 : // Honor -version.
233 : //
234 : // FIXME: Use a better -version message?
0: branch 1 not taken
2514: branch 2 taken
235 2514: if (Clang.getFrontendOpts().ShowVersion) {
236 0: llvm::cl::PrintVersionMessage();
237 0: return 0;
238 : }
239 :
240 : // Create the actual diagnostics engine.
241 2514: Clang.createDiagnostics(ArgEnd - ArgBegin, const_cast<char**>(ArgBegin));
0: branch 1 not taken
2514: branch 2 taken
242 2514: if (!Clang.hasDiagnostics())
243 0: return 1;
244 :
245 : // Set an error handler, so that any LLVM backend diagnostics go through our
246 : // error handler.
247 : llvm::llvm_install_error_handler(LLVMErrorHandler,
248 2514: static_cast<void*>(&Clang.getDiagnostics()));
249 :
250 2514: DiagsBuffer.FlushDiagnostics(Clang.getDiagnostics());
251 :
252 : // Load any requested plugins.
0: branch 1 not taken
2514: branch 2 taken
253 5028: for (unsigned i = 0,
254 2514: e = Clang.getFrontendOpts().Plugins.size(); i != e; ++i) {
255 0: const std::string &Path = Clang.getFrontendOpts().Plugins[i];
256 0: std::string Error;
0: branch 2 not taken
0: branch 3 not taken
257 0: if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error))
258 0: Diags.Report(diag::err_fe_unable_to_load_plugin) << Path << Error;
259 : }
260 :
261 : // If there were errors in processing arguments, don't do anything else.
262 2514: bool Success = false;
2513: branch 2 taken
1: branch 3 taken
263 2514: if (!Clang.getDiagnostics().getNumErrors()) {
264 : // Create and execute the frontend action.
265 2513: llvm::OwningPtr<FrontendAction> Act(CreateFrontendAction(Clang));
2513: branch 1 taken
0: branch 2 not taken
266 2513: if (Act)
267 2513: Success = Clang.ExecuteAction(*Act);
268 : }
269 :
270 : // Managed static deconstruction. Useful for making things like
271 : // -time-passes usable.
272 2514: llvm::llvm_shutdown();
273 :
274 2514: return !Success;
275 : }
Generated: 2010-02-10 01:31 by zcov