Home | History | Annotate | Download | only in Frontend
      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