llvm-project/clang/lib/Frontend/FrontendActions.cpp
Daniel Dunbar c1b1729b66 Break Frontend's dependency on Rewrite, Checker and CodeGen in shared library configuration
Currently, all AST consumers are located in the Frontend library,
meaning that in a shared library configuration, Frontend has a
dependency on Rewrite, Checker and CodeGen.  This is suboptimal for
clients which only wish to make use of the frontend.  CodeGen in
particular introduces a large number of unwanted dependencies.

This patch breaks the dependency by moving all AST consumers with
dependencies on Rewrite, Checker and/or CodeGen to their respective
libraries.  The patch therefore introduces dependencies in the other
direction (i.e. from Rewrite, Checker and CodeGen to Frontend).

After applying this patch, Clang builds correctly using CMake and
shared libraries ("cmake -DBUILD_SHARED_LIBS=ON").

N.B. This patch includes file renames which are indicated in the
patch body.

Changes in this revision of the patch:
 - Fixed some copy-paste mistakes in the header files
 - Modified certain aspects of the coding to comply with the LLVM
   Coding Standards

llvm-svn: 106010
2010-06-15 17:48:49 +00:00

194 lines
6.4 KiB
C++

//===--- FrontendActions.cpp ----------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "clang/Frontend/FrontendActions.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Lex/Pragma.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/Parser.h"
#include "clang/Basic/FileManager.h"
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/Utils.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
//===----------------------------------------------------------------------===//
// Custom Actions
//===----------------------------------------------------------------------===//
ASTConsumer *InitOnlyAction::CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef InFile) {
return new ASTConsumer();
}
void InitOnlyAction::ExecuteAction() {
}
//===----------------------------------------------------------------------===//
// AST Consumer Actions
//===----------------------------------------------------------------------===//
ASTConsumer *ASTPrintAction::CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef InFile) {
if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
return CreateASTPrinter(OS);
return 0;
}
ASTConsumer *ASTPrintXMLAction::CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef InFile) {
if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "xml"))
return CreateASTPrinterXML(OS);
return 0;
}
ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef InFile) {
return CreateASTDumper();
}
ASTConsumer *ASTViewAction::CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef InFile) {
return CreateASTViewer();
}
ASTConsumer *DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef InFile) {
return CreateDeclContextPrinter();
}
ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef InFile) {
const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
if (CI.getFrontendOpts().RelocatablePCH &&
Sysroot.empty()) {
CI.getDiagnostics().Report(diag::err_relocatable_without_without_isysroot);
return 0;
}
llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, InFile);
if (!OS)
return 0;
if (CI.getFrontendOpts().RelocatablePCH)
return CreatePCHGenerator(CI.getPreprocessor(), OS, Sysroot.c_str());
return CreatePCHGenerator(CI.getPreprocessor(), OS);
}
ASTConsumer *InheritanceViewAction::CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef InFile) {
return CreateInheritanceViewer(CI.getFrontendOpts().ViewClassInheritance);
}
ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef InFile) {
return new ASTConsumer();
}
//===----------------------------------------------------------------------===//
// Preprocessor Actions
//===----------------------------------------------------------------------===//
void DumpRawTokensAction::ExecuteAction() {
Preprocessor &PP = getCompilerInstance().getPreprocessor();
SourceManager &SM = PP.getSourceManager();
// Start lexing the specified input file.
const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOptions());
RawLex.SetKeepWhitespaceMode(true);
Token RawTok;
RawLex.LexFromRawLexer(RawTok);
while (RawTok.isNot(tok::eof)) {
PP.DumpToken(RawTok, true);
llvm::errs() << "\n";
RawLex.LexFromRawLexer(RawTok);
}
}
void DumpTokensAction::ExecuteAction() {
Preprocessor &PP = getCompilerInstance().getPreprocessor();
// Start preprocessing the specified input file.
Token Tok;
PP.EnterMainSourceFile();
do {
PP.Lex(Tok);
PP.DumpToken(Tok, true);
llvm::errs() << "\n";
} while (Tok.isNot(tok::eof));
}
void GeneratePTHAction::ExecuteAction() {
CompilerInstance &CI = getCompilerInstance();
if (CI.getFrontendOpts().OutputFile.empty() ||
CI.getFrontendOpts().OutputFile == "-") {
// FIXME: Don't fail this way.
// FIXME: Verify that we can actually seek in the given file.
llvm::report_fatal_error("PTH requires a seekable file for output!");
}
llvm::raw_fd_ostream *OS =
CI.createDefaultOutputFile(true, getCurrentFile());
if (!OS) return;
CacheTokens(CI.getPreprocessor(), OS);
}
void ParseOnlyAction::ExecuteAction() {
Preprocessor &PP = getCompilerInstance().getPreprocessor();
llvm::OwningPtr<Action> PA(new MinimalAction(PP));
Parser P(PP, *PA);
PP.EnterMainSourceFile();
P.ParseTranslationUnit();
}
void PreprocessOnlyAction::ExecuteAction() {
Preprocessor &PP = getCompilerInstance().getPreprocessor();
// Ignore unknown pragmas.
PP.AddPragmaHandler(0, new EmptyPragmaHandler());
Token Tok;
// Start parsing the specified input file.
PP.EnterMainSourceFile();
do {
PP.Lex(Tok);
} while (Tok.isNot(tok::eof));
}
void PrintParseAction::ExecuteAction() {
CompilerInstance &CI = getCompilerInstance();
Preprocessor &PP = getCompilerInstance().getPreprocessor();
llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile());
if (!OS) return;
llvm::OwningPtr<Action> PA(CreatePrintParserActionsAction(PP, OS));
Parser P(PP, *PA);
PP.EnterMainSourceFile();
P.ParseTranslationUnit();
}
void PrintPreprocessedAction::ExecuteAction() {
CompilerInstance &CI = getCompilerInstance();
// Output file needs to be set to 'Binary', to avoid converting Unix style
// line feeds (<LF>) to Microsoft style line feeds (<CR><LF>).
llvm::raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
if (!OS) return;
DoPrintPreprocessedInput(CI.getPreprocessor(), OS,
CI.getPreprocessorOutputOpts());
}