summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp90
1 files changed, 65 insertions, 25 deletions
diff --git a/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp b/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp
index 7b06c7e..6f84da9 100644
--- a/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp
+++ b/contrib/llvm/tools/clang/lib/Frontend/FrontendActions.cpp
@@ -22,6 +22,8 @@
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/system_error.h"
+
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -29,7 +31,7 @@ using namespace clang;
//===----------------------------------------------------------------------===//
ASTConsumer *InitOnlyAction::CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile) {
+ StringRef InFile) {
return new ASTConsumer();
}
@@ -41,20 +43,20 @@ void InitOnlyAction::ExecuteAction() {
//===----------------------------------------------------------------------===//
ASTConsumer *ASTPrintAction::CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile) {
- if (llvm::raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
+ StringRef InFile) {
+ if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
return CreateASTPrinter(OS);
return 0;
}
ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile) {
+ StringRef InFile) {
return CreateASTDumper();
}
ASTConsumer *ASTDumpXMLAction::CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile) {
- llvm::raw_ostream *OS;
+ StringRef InFile) {
+ raw_ostream *OS;
if (CI.getFrontendOpts().OutputFile.empty())
OS = &llvm::outs();
else
@@ -64,35 +66,34 @@ ASTConsumer *ASTDumpXMLAction::CreateASTConsumer(CompilerInstance &CI,
}
ASTConsumer *ASTViewAction::CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile) {
+ StringRef InFile) {
return CreateASTViewer();
}
ASTConsumer *DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile) {
+ StringRef InFile) {
return CreateDeclContextPrinter();
}
ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile) {
+ StringRef InFile) {
std::string Sysroot;
std::string OutputFile;
- llvm::raw_ostream *OS = 0;
- bool Chaining;
- if (ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile, OS, Chaining))
+ raw_ostream *OS = 0;
+ if (ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile, OS))
return 0;
- const char *isysroot = CI.getFrontendOpts().RelocatablePCH ?
- Sysroot.c_str() : 0;
- return new PCHGenerator(CI.getPreprocessor(), OutputFile, Chaining, isysroot, OS);
+ if (!CI.getFrontendOpts().RelocatablePCH)
+ Sysroot.clear();
+ return new PCHGenerator(CI.getPreprocessor(), OutputFile, MakeModule,
+ Sysroot, OS);
}
bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI,
- llvm::StringRef InFile,
+ StringRef InFile,
std::string &Sysroot,
std::string &OutputFile,
- llvm::raw_ostream *&OS,
- bool &Chaining) {
+ raw_ostream *&OS) {
Sysroot = CI.getHeaderSearchOpts().Sysroot;
if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) {
CI.getDiagnostics().Report(diag::err_relocatable_without_isysroot);
@@ -101,19 +102,19 @@ bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI,
// We use createOutputFile here because this is exposed via libclang, and we
// must disable the RemoveFileOnSignal behavior.
+ // We use a temporary to avoid race conditions.
OS = CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
- /*RemoveFileOnSignal=*/false, InFile);
+ /*RemoveFileOnSignal=*/false, InFile,
+ /*Extension=*/"", /*useTemporary=*/true);
if (!OS)
return true;
OutputFile = CI.getFrontendOpts().OutputFile;
- Chaining = CI.getInvocation().getFrontendOpts().ChainedPCH &&
- !CI.getPreprocessorOpts().ImplicitPCHInclude.empty();
return false;
}
ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile) {
+ StringRef InFile) {
return new ASTConsumer();
}
@@ -182,9 +183,48 @@ void PreprocessOnlyAction::ExecuteAction() {
void PrintPreprocessedAction::ExecuteAction() {
CompilerInstance &CI = getCompilerInstance();
- // Output file needs to be set to 'Binary', to avoid converting Unix style
+ // Output file may need 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());
+ //
+ // Look to see what type of line endings the file uses. If there's a
+ // CRLF, then we won't open the file up in binary mode. If there is
+ // just an LF or CR, then we will open the file up in binary mode.
+ // In this fashion, the output format should match the input format, unless
+ // the input format has inconsistent line endings.
+ //
+ // This should be a relatively fast operation since most files won't have
+ // all of their source code on a single line. However, that is still a
+ // concern, so if we scan for too long, we'll just assume the file should
+ // be opened in binary mode.
+ bool BinaryMode = true;
+ bool InvalidFile = false;
+ const SourceManager& SM = CI.getSourceManager();
+ const llvm::MemoryBuffer *Buffer = SM.getBuffer(SM.getMainFileID(),
+ &InvalidFile);
+ if (!InvalidFile) {
+ const char *cur = Buffer->getBufferStart();
+ const char *end = Buffer->getBufferEnd();
+ const char *next = (cur != end) ? cur + 1 : end;
+
+ // Limit ourselves to only scanning 256 characters into the source
+ // file. This is mostly a sanity check in case the file has no
+ // newlines whatsoever.
+ if (end - cur > 256) end = cur + 256;
+
+ while (next < end) {
+ if (*cur == 0x0D) { // CR
+ if (*next == 0x0A) // CRLF
+ BinaryMode = false;
+
+ break;
+ } else if (*cur == 0x0A) // LF
+ break;
+
+ ++cur, ++next;
+ }
+ }
+
+ raw_ostream *OS = CI.createDefaultOutputFile(BinaryMode, getCurrentFile());
if (!OS) return;
DoPrintPreprocessedInput(CI.getPreprocessor(), OS,
@@ -217,7 +257,7 @@ void PrintPreambleAction::ExecuteAction() {
llvm::MemoryBuffer *Buffer
= CI.getFileManager().getBufferForFile(getCurrentFile());
if (Buffer) {
- unsigned Preamble = Lexer::ComputePreamble(Buffer).first;
+ unsigned Preamble = Lexer::ComputePreamble(Buffer, CI.getLangOpts()).first;
llvm::outs().write(Buffer->getBufferStart(), Preamble);
delete Buffer;
}
OpenPOWER on IntegriCloud