cc1_main.cpp revision 1e69fe3a9f0a42b32a3000bda51677d51416564e
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/Basic/FileManager.h" 18#include "clang/Basic/SourceManager.h" 19#include "clang/Basic/TargetInfo.h" 20#include "clang/Basic/Version.h" 21#include "clang/Driver/Arg.h" 22#include "clang/Driver/ArgList.h" 23#include "clang/Driver/CC1Options.h" 24#include "clang/Driver/DriverDiagnostic.h" 25#include "clang/Driver/OptTable.h" 26#include "clang/Frontend/CompilerInstance.h" 27#include "clang/Frontend/CompilerInvocation.h" 28#include "clang/Frontend/FrontendActions.h" 29#include "clang/Frontend/FrontendDiagnostic.h" 30#include "clang/Frontend/FrontendPluginRegistry.h" 31#include "clang/Frontend/TextDiagnosticBuffer.h" 32#include "clang/Frontend/TextDiagnosticPrinter.h" 33#include "clang/Frontend/VerifyDiagnosticsClient.h" 34#include "llvm/LLVMContext.h" 35#include "llvm/ADT/OwningPtr.h" 36#include "llvm/Support/ErrorHandling.h" 37#include "llvm/Support/ManagedStatic.h" 38#include "llvm/Support/PrettyStackTrace.h" 39#include "llvm/Support/raw_ostream.h" 40#include "llvm/System/DynamicLibrary.h" 41#include "llvm/System/Host.h" 42#include "llvm/System/Path.h" 43#include "llvm/System/Signals.h" 44#include "llvm/Target/TargetSelect.h" 45#include <cstdio> 46using namespace clang; 47 48//===----------------------------------------------------------------------===// 49// Main driver 50//===----------------------------------------------------------------------===// 51 52void LLVMErrorHandler(void *UserData, const std::string &Message) { 53 Diagnostic &Diags = *static_cast<Diagnostic*>(UserData); 54 55 Diags.Report(diag::err_fe_error_backend) << Message; 56 57 // We cannot recover from llvm errors. 58 exit(1); 59} 60 61static FrontendAction *CreateFrontendAction(CompilerInstance &CI) { 62 using namespace clang::frontend; 63 64 switch (CI.getFrontendOpts().ProgramAction) { 65 default: 66 llvm_unreachable("Invalid program action!"); 67 68 case ASTDump: return new ASTDumpAction(); 69 case ASTPrint: return new ASTPrintAction(); 70 case ASTPrintXML: return new ASTPrintXMLAction(); 71 case ASTView: return new ASTViewAction(); 72 case DumpRawTokens: return new DumpRawTokensAction(); 73 case DumpRecordLayouts: return new DumpRecordAction(); 74 case DumpTokens: return new DumpTokensAction(); 75 case EmitAssembly: return new EmitAssemblyAction(); 76 case EmitBC: return new EmitBCAction(); 77 case EmitHTML: return new HTMLPrintAction(); 78 case EmitLLVM: return new EmitLLVMAction(); 79 case EmitLLVMOnly: return new EmitLLVMOnlyAction(); 80 case FixIt: return new FixItAction(); 81 case GeneratePCH: return new GeneratePCHAction(); 82 case GeneratePTH: return new GeneratePTHAction(); 83 case InheritanceView: return new InheritanceViewAction(); 84 case ParseNoop: return new ParseOnlyAction(); 85 case ParsePrintCallbacks: return new PrintParseAction(); 86 case ParseSyntaxOnly: return new SyntaxOnlyAction(); 87 88 case PluginAction: { 89 if (CI.getFrontendOpts().ActionName == "help") { 90 llvm::errs() << "clang -cc1 plugins:\n"; 91 for (FrontendPluginRegistry::iterator it = 92 FrontendPluginRegistry::begin(), 93 ie = FrontendPluginRegistry::end(); 94 it != ie; ++it) 95 llvm::errs() << " " << it->getName() << " - " << it->getDesc() << "\n"; 96 return 0; 97 } 98 99 for (FrontendPluginRegistry::iterator it = 100 FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); 101 it != ie; ++it) { 102 if (it->getName() == CI.getFrontendOpts().ActionName) 103 return it->instantiate(); 104 } 105 106 CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) 107 << CI.getFrontendOpts().ActionName; 108 return 0; 109 } 110 111 case PrintDeclContext: return new DeclContextPrintAction(); 112 case PrintPreprocessedInput: return new PrintPreprocessedAction(); 113 case RewriteBlocks: return new RewriteBlocksAction(); 114 case RewriteMacros: return new RewriteMacrosAction(); 115 case RewriteObjC: return new RewriteObjCAction(); 116 case RewriteTest: return new RewriteTestAction(); 117 case RunAnalysis: return new AnalysisAction(); 118 case RunPreprocessorOnly: return new PreprocessOnlyAction(); 119 } 120} 121 122// FIXME: Define the need for this testing away. 123static int cc1_test(Diagnostic &Diags, 124 const char **ArgBegin, const char **ArgEnd) { 125 using namespace clang::driver; 126 127 llvm::errs() << "cc1 argv:"; 128 for (const char **i = ArgBegin; i != ArgEnd; ++i) 129 llvm::errs() << " \"" << *i << '"'; 130 llvm::errs() << "\n"; 131 132 // Parse the arguments. 133 OptTable *Opts = createCC1OptTable(); 134 unsigned MissingArgIndex, MissingArgCount; 135 InputArgList *Args = Opts->ParseArgs(ArgBegin, ArgEnd, 136 MissingArgIndex, MissingArgCount); 137 138 // Check for missing argument error. 139 if (MissingArgCount) 140 Diags.Report(clang::diag::err_drv_missing_argument) 141 << Args->getArgString(MissingArgIndex) << MissingArgCount; 142 143 // Dump the parsed arguments. 144 llvm::errs() << "cc1 parsed options:\n"; 145 for (ArgList::const_iterator it = Args->begin(), ie = Args->end(); 146 it != ie; ++it) 147 (*it)->dump(); 148 149 // Create a compiler invocation. 150 llvm::errs() << "cc1 creating invocation.\n"; 151 CompilerInvocation Invocation; 152 CompilerInvocation::CreateFromArgs(Invocation, ArgBegin, ArgEnd, Diags); 153 154 // Convert the invocation back to argument strings. 155 std::vector<std::string> InvocationArgs; 156 Invocation.toArgs(InvocationArgs); 157 158 // Dump the converted arguments. 159 llvm::SmallVector<const char*, 32> Invocation2Args; 160 llvm::errs() << "invocation argv :"; 161 for (unsigned i = 0, e = InvocationArgs.size(); i != e; ++i) { 162 Invocation2Args.push_back(InvocationArgs[i].c_str()); 163 llvm::errs() << " \"" << InvocationArgs[i] << '"'; 164 } 165 llvm::errs() << "\n"; 166 167 // Convert those arguments to another invocation, and check that we got the 168 // same thing. 169 CompilerInvocation Invocation2; 170 CompilerInvocation::CreateFromArgs(Invocation2, Invocation2Args.begin(), 171 Invocation2Args.end(), Diags); 172 173 // FIXME: Implement CompilerInvocation comparison. 174 if (true) { 175 //llvm::errs() << "warning: Invocations differ!\n"; 176 177 std::vector<std::string> Invocation2Args; 178 Invocation2.toArgs(Invocation2Args); 179 llvm::errs() << "invocation2 argv:"; 180 for (unsigned i = 0, e = Invocation2Args.size(); i != e; ++i) 181 llvm::errs() << " \"" << Invocation2Args[i] << '"'; 182 llvm::errs() << "\n"; 183 } 184 185 return 0; 186} 187 188int cc1_main(const char **ArgBegin, const char **ArgEnd, 189 const char *Argv0, void *MainAddr) { 190 llvm::sys::PrintStackTraceOnErrorSignal(); 191 llvm::PrettyStackTraceProgram X(ArgBegin - ArgEnd, ArgBegin); 192 CompilerInstance Clang(&llvm::getGlobalContext(), false); 193 194 // Run clang -cc1 test. 195 if (ArgBegin != ArgEnd && llvm::StringRef(ArgBegin[0]) == "-cc1test") { 196 TextDiagnosticPrinter DiagClient(llvm::errs(), DiagnosticOptions()); 197 Diagnostic Diags(&DiagClient); 198 return cc1_test(Diags, ArgBegin + 1, ArgEnd); 199 } 200 201 // Initialize targets first, so that --version shows registered targets. 202 llvm::InitializeAllTargets(); 203 llvm::InitializeAllAsmPrinters(); 204 205 // Buffer diagnostics from argument parsing so that we can output them using a 206 // well formed diagnostic object. 207 TextDiagnosticBuffer DiagsBuffer; 208 Diagnostic Diags(&DiagsBuffer); 209 CompilerInvocation::CreateFromArgs(Clang.getInvocation(), ArgBegin, ArgEnd, 210 Diags); 211 212 // Infer the builtin include path if unspecified. 213 if (Clang.getInvocation().getHeaderSearchOpts().UseBuiltinIncludes && 214 Clang.getInvocation().getHeaderSearchOpts().BuiltinIncludePath.empty()) 215 Clang.getInvocation().getHeaderSearchOpts().BuiltinIncludePath = 216 CompilerInvocation::GetBuiltinIncludePath(Argv0, MainAddr); 217 218 // Honor -help. 219 if (Clang.getInvocation().getFrontendOpts().ShowHelp) { 220 llvm::OwningPtr<driver::OptTable> Opts(driver::createCC1OptTable()); 221 Opts->PrintHelp(llvm::outs(), "clang -cc1", 222 "LLVM 'Clang' Compiler: http://clang.llvm.org"); 223 return 0; 224 } 225 226 // Honor -version. 227 // 228 // FIXME: Use a better -version message? 229 if (Clang.getInvocation().getFrontendOpts().ShowVersion) { 230 llvm::cl::PrintVersionMessage(); 231 return 0; 232 } 233 234 // Create the actual diagnostics engine. 235 Clang.createDiagnostics(ArgEnd - ArgBegin, const_cast<char**>(ArgBegin)); 236 if (!Clang.hasDiagnostics()) 237 return 1; 238 239 // Set an error handler, so that any LLVM backend diagnostics go through our 240 // error handler. 241 llvm::llvm_install_error_handler(LLVMErrorHandler, 242 static_cast<void*>(&Clang.getDiagnostics())); 243 244 DiagsBuffer.FlushDiagnostics(Clang.getDiagnostics()); 245 246 // Load any requested plugins. 247 for (unsigned i = 0, 248 e = Clang.getFrontendOpts().Plugins.size(); i != e; ++i) { 249 const std::string &Path = Clang.getFrontendOpts().Plugins[i]; 250 std::string Error; 251 if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) 252 Diags.Report(diag::err_fe_unable_to_load_plugin) << Path << Error; 253 } 254 255 // If there were any errors in processing arguments, exit now. 256 if (Clang.getDiagnostics().getNumErrors()) 257 return 1; 258 259 // Create the target instance. 260 Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(), 261 Clang.getTargetOpts())); 262 if (!Clang.hasTarget()) 263 return 1; 264 265 // Inform the target of the language options 266 // 267 // FIXME: We shouldn't need to do this, the target should be immutable once 268 // created. This complexity should be lifted elsewhere. 269 Clang.getTarget().setForcedLangOptions(Clang.getLangOpts()); 270 271 // Validate/process some options 272 if (Clang.getHeaderSearchOpts().Verbose) 273 llvm::errs() << "clang -cc1 version " CLANG_VERSION_STRING 274 << " based upon " << PACKAGE_STRING 275 << " hosted on " << llvm::sys::getHostTriple() << "\n"; 276 277 if (Clang.getFrontendOpts().ShowTimers) 278 Clang.createFrontendTimer(); 279 280 for (unsigned i = 0, e = Clang.getFrontendOpts().Inputs.size(); i != e; ++i) { 281 const std::string &InFile = Clang.getFrontendOpts().Inputs[i].second; 282 283 // If we aren't using an AST file, setup the file and source managers and 284 // the preprocessor. 285 bool IsAST = 286 Clang.getFrontendOpts().Inputs[i].first == FrontendOptions::IK_AST; 287 if (!IsAST) { 288 if (!i) { 289 // Create a file manager object to provide access to and cache the 290 // filesystem. 291 Clang.createFileManager(); 292 293 // Create the source manager. 294 Clang.createSourceManager(); 295 } else { 296 // Reset the ID tables if we are reusing the SourceManager. 297 Clang.getSourceManager().clearIDTables(); 298 } 299 300 // Create the preprocessor. 301 Clang.createPreprocessor(); 302 } 303 304 llvm::OwningPtr<FrontendAction> Act(CreateFrontendAction(Clang)); 305 if (!Act) 306 break; 307 308 if (Act->BeginSourceFile(Clang, InFile, IsAST)) { 309 Act->Execute(); 310 Act->EndSourceFile(); 311 } 312 } 313 314 if (Clang.getDiagnosticOpts().ShowCarets) 315 if (unsigned NumDiagnostics = Clang.getDiagnostics().getNumDiagnostics()) 316 fprintf(stderr, "%d diagnostic%s generated.\n", NumDiagnostics, 317 (NumDiagnostics == 1 ? "" : "s")); 318 319 if (Clang.getFrontendOpts().ShowStats) { 320 Clang.getFileManager().PrintStats(); 321 fprintf(stderr, "\n"); 322 } 323 324 // Return the appropriate status when verifying diagnostics. 325 // 326 // FIXME: If we could make getNumErrors() do the right thing, we wouldn't need 327 // this. 328 if (Clang.getDiagnosticOpts().VerifyDiagnostics) 329 return static_cast<VerifyDiagnosticsClient&>( 330 Clang.getDiagnosticClient()).HadErrors(); 331 332 // Managed static deconstruction. Useful for making things like 333 // -time-passes usable. 334 llvm::llvm_shutdown(); 335 336 return (Clang.getDiagnostics().getNumErrors() != 0); 337} 338