1 //===--- FrontendActions.cpp ----------------------------------------------===// 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 #include "clang/Frontend/FrontendActions.h" 11 #include "clang/AST/ASTConsumer.h" 12 #include "clang/Lex/Pragma.h" 13 #include "clang/Lex/Preprocessor.h" 14 #include "clang/Parse/Parser.h" 15 #include "clang/Basic/FileManager.h" 16 #include "clang/Frontend/ASTConsumers.h" 17 #include "clang/Frontend/ASTUnit.h" 18 #include "clang/Frontend/CompilerInstance.h" 19 #include "clang/Frontend/FrontendDiagnostic.h" 20 #include "clang/Frontend/Utils.h" 21 #include "clang/Serialization/ASTWriter.h" 22 #include "llvm/ADT/OwningPtr.h" 23 #include "llvm/Support/MemoryBuffer.h" 24 #include "llvm/Support/raw_ostream.h" 25 #include "llvm/Support/system_error.h" 26 27 using namespace clang; 28 29 //===----------------------------------------------------------------------===// 30 // Custom Actions 31 //===----------------------------------------------------------------------===// 32 33 ASTConsumer *InitOnlyAction::CreateASTConsumer(CompilerInstance &CI, 34 StringRef InFile) { 35 return new ASTConsumer(); 36 } 37 38 void InitOnlyAction::ExecuteAction() { 39 } 40 41 //===----------------------------------------------------------------------===// 42 // AST Consumer Actions 43 //===----------------------------------------------------------------------===// 44 45 ASTConsumer *ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, 46 StringRef InFile) { 47 if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile)) 48 return CreateASTPrinter(OS); 49 return 0; 50 } 51 52 ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, 53 StringRef InFile) { 54 return CreateASTDumper(); 55 } 56 57 ASTConsumer *ASTDumpXMLAction::CreateASTConsumer(CompilerInstance &CI, 58 StringRef InFile) { 59 raw_ostream *OS; 60 if (CI.getFrontendOpts().OutputFile.empty()) 61 OS = &llvm::outs(); 62 else 63 OS = CI.createDefaultOutputFile(false, InFile); 64 if (!OS) return 0; 65 return CreateASTDumperXML(*OS); 66 } 67 68 ASTConsumer *ASTViewAction::CreateASTConsumer(CompilerInstance &CI, 69 StringRef InFile) { 70 return CreateASTViewer(); 71 } 72 73 ASTConsumer *DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI, 74 StringRef InFile) { 75 return CreateDeclContextPrinter(); 76 } 77 78 ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, 79 StringRef InFile) { 80 std::string Sysroot; 81 std::string OutputFile; 82 raw_ostream *OS = 0; 83 if (ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile, OS)) 84 return 0; 85 86 if (!CI.getFrontendOpts().RelocatablePCH) 87 Sysroot.clear(); 88 return new PCHGenerator(CI.getPreprocessor(), OutputFile, MakeModule, 89 Sysroot, OS); 90 } 91 92 bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI, 93 StringRef InFile, 94 std::string &Sysroot, 95 std::string &OutputFile, 96 raw_ostream *&OS) { 97 Sysroot = CI.getHeaderSearchOpts().Sysroot; 98 if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) { 99 CI.getDiagnostics().Report(diag::err_relocatable_without_isysroot); 100 return true; 101 } 102 103 // We use createOutputFile here because this is exposed via libclang, and we 104 // must disable the RemoveFileOnSignal behavior. 105 // We use a temporary to avoid race conditions. 106 OS = CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true, 107 /*RemoveFileOnSignal=*/false, InFile, 108 /*Extension=*/"", /*useTemporary=*/true); 109 if (!OS) 110 return true; 111 112 OutputFile = CI.getFrontendOpts().OutputFile; 113 return false; 114 } 115 116 ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI, 117 StringRef InFile) { 118 return new ASTConsumer(); 119 } 120 121 //===----------------------------------------------------------------------===// 122 // Preprocessor Actions 123 //===----------------------------------------------------------------------===// 124 125 void DumpRawTokensAction::ExecuteAction() { 126 Preprocessor &PP = getCompilerInstance().getPreprocessor(); 127 SourceManager &SM = PP.getSourceManager(); 128 129 // Start lexing the specified input file. 130 const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID()); 131 Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOptions()); 132 RawLex.SetKeepWhitespaceMode(true); 133 134 Token RawTok; 135 RawLex.LexFromRawLexer(RawTok); 136 while (RawTok.isNot(tok::eof)) { 137 PP.DumpToken(RawTok, true); 138 llvm::errs() << "\n"; 139 RawLex.LexFromRawLexer(RawTok); 140 } 141 } 142 143 void DumpTokensAction::ExecuteAction() { 144 Preprocessor &PP = getCompilerInstance().getPreprocessor(); 145 // Start preprocessing the specified input file. 146 Token Tok; 147 PP.EnterMainSourceFile(); 148 do { 149 PP.Lex(Tok); 150 PP.DumpToken(Tok, true); 151 llvm::errs() << "\n"; 152 } while (Tok.isNot(tok::eof)); 153 } 154 155 void GeneratePTHAction::ExecuteAction() { 156 CompilerInstance &CI = getCompilerInstance(); 157 if (CI.getFrontendOpts().OutputFile.empty() || 158 CI.getFrontendOpts().OutputFile == "-") { 159 // FIXME: Don't fail this way. 160 // FIXME: Verify that we can actually seek in the given file. 161 llvm::report_fatal_error("PTH requires a seekable file for output!"); 162 } 163 llvm::raw_fd_ostream *OS = 164 CI.createDefaultOutputFile(true, getCurrentFile()); 165 if (!OS) return; 166 167 CacheTokens(CI.getPreprocessor(), OS); 168 } 169 170 void PreprocessOnlyAction::ExecuteAction() { 171 Preprocessor &PP = getCompilerInstance().getPreprocessor(); 172 173 // Ignore unknown pragmas. 174 PP.AddPragmaHandler(new EmptyPragmaHandler()); 175 176 Token Tok; 177 // Start parsing the specified input file. 178 PP.EnterMainSourceFile(); 179 do { 180 PP.Lex(Tok); 181 } while (Tok.isNot(tok::eof)); 182 } 183 184 void PrintPreprocessedAction::ExecuteAction() { 185 CompilerInstance &CI = getCompilerInstance(); 186 // Output file may need to be set to 'Binary', to avoid converting Unix style 187 // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>). 188 // 189 // Look to see what type of line endings the file uses. If there's a 190 // CRLF, then we won't open the file up in binary mode. If there is 191 // just an LF or CR, then we will open the file up in binary mode. 192 // In this fashion, the output format should match the input format, unless 193 // the input format has inconsistent line endings. 194 // 195 // This should be a relatively fast operation since most files won't have 196 // all of their source code on a single line. However, that is still a 197 // concern, so if we scan for too long, we'll just assume the file should 198 // be opened in binary mode. 199 bool BinaryMode = true; 200 bool InvalidFile = false; 201 const SourceManager& SM = CI.getSourceManager(); 202 const llvm::MemoryBuffer *Buffer = SM.getBuffer(SM.getMainFileID(), 203 &InvalidFile); 204 if (!InvalidFile) { 205 const char *cur = Buffer->getBufferStart(); 206 const char *end = Buffer->getBufferEnd(); 207 const char *next = (cur != end) ? cur + 1 : end; 208 209 // Limit ourselves to only scanning 256 characters into the source 210 // file. This is mostly a sanity check in case the file has no 211 // newlines whatsoever. 212 if (end - cur > 256) end = cur + 256; 213 214 while (next < end) { 215 if (*cur == 0x0D) { // CR 216 if (*next == 0x0A) // CRLF 217 BinaryMode = false; 218 219 break; 220 } else if (*cur == 0x0A) // LF 221 break; 222 223 ++cur, ++next; 224 } 225 } 226 227 raw_ostream *OS = CI.createDefaultOutputFile(BinaryMode, getCurrentFile()); 228 if (!OS) return; 229 230 DoPrintPreprocessedInput(CI.getPreprocessor(), OS, 231 CI.getPreprocessorOutputOpts()); 232 } 233 234 void PrintPreambleAction::ExecuteAction() { 235 switch (getCurrentFileKind()) { 236 case IK_C: 237 case IK_CXX: 238 case IK_ObjC: 239 case IK_ObjCXX: 240 case IK_OpenCL: 241 case IK_CUDA: 242 break; 243 244 case IK_None: 245 case IK_Asm: 246 case IK_PreprocessedC: 247 case IK_PreprocessedCXX: 248 case IK_PreprocessedObjC: 249 case IK_PreprocessedObjCXX: 250 case IK_AST: 251 case IK_LLVM_IR: 252 // We can't do anything with these. 253 return; 254 } 255 256 CompilerInstance &CI = getCompilerInstance(); 257 llvm::MemoryBuffer *Buffer 258 = CI.getFileManager().getBufferForFile(getCurrentFile()); 259 if (Buffer) { 260 unsigned Preamble = Lexer::ComputePreamble(Buffer, CI.getLangOpts()).first; 261 llvm::outs().write(Buffer->getBufferStart(), Preamble); 262 delete Buffer; 263 } 264 } 265