class Preprocessor: Now owns the "predefines" char*; it deletes [] it in its dstor.
clang.cpp: InitializePreprocessor now makes a copy of the contents of PredefinesBuffer and
passes it to the preprocessor object.
clang.cpp: DriverPreprocessorFactory now calls "InitializePreprocessor" instead of this being done in main().
html::HighlightMacros() now takes a PreprocessorFactory, allowing it to conjure up a new
Preprocessor to highlight macros.
class HTMLDiagnostics now takes a PreprocessorFactory* that it can use for html::HighlightMacros().
Updated clients of HTMLDiagnostics to use this new interface.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49875 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Driver/clang.cpp b/Driver/clang.cpp
index cbd2725..1a6db48 100644
--- a/Driver/clang.cpp
+++ b/Driver/clang.cpp
@@ -48,6 +48,7 @@
#include "llvm/System/Path.h"
#include <memory>
#include <fstream>
+#include <algorithm>
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -586,26 +587,31 @@
/// input file. If a failure happens, it returns 0.
///
static unsigned InitializePreprocessor(Preprocessor &PP,
+ bool InitializeSourceMgr,
const std::string &InFile,
std::vector<char> &PredefineBuffer) {
+
FileManager &FileMgr = PP.getFileManager();
// Figure out where to get and map in the main file.
SourceManager &SourceMgr = PP.getSourceManager();
- if (InFile != "-") {
- const FileEntry *File = FileMgr.getFile(InFile);
- if (File) SourceMgr.createMainFileID(File, SourceLocation());
- if (SourceMgr.getMainFileID() == 0) {
- fprintf(stderr, "Error reading '%s'!\n",InFile.c_str());
- return 0;
- }
- } else {
- llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getSTDIN();
- if (SB) SourceMgr.createMainFileIDForMemBuffer(SB);
- if (SourceMgr.getMainFileID() == 0) {
- fprintf(stderr, "Error reading standard input! Empty?\n");
- return 0;
+
+ if (InitializeSourceMgr) {
+ if (InFile != "-") {
+ const FileEntry *File = FileMgr.getFile(InFile);
+ if (File) SourceMgr.createMainFileID(File, SourceLocation());
+ if (SourceMgr.getMainFileID() == 0) {
+ fprintf(stderr, "Error reading '%s'!\n",InFile.c_str());
+ return 0;
+ }
+ } else {
+ llvm::MemoryBuffer *SB = llvm::MemoryBuffer::getSTDIN();
+ if (SB) SourceMgr.createMainFileIDForMemBuffer(SB);
+ if (SourceMgr.getMainFileID() == 0) {
+ fprintf(stderr, "Error reading standard input! Empty?\n");
+ return 0;
+ }
}
}
@@ -625,9 +631,13 @@
for (unsigned i = 0, e = ImplicitIncludes.size(); i != e; ++i)
AddImplicitInclude(PredefineBuffer, ImplicitIncludes[i]);
- // Null terminate PredefinedBuffer and add it.
+ // Null terminate PredefinedBuffer and add it. We actually need to make a
+ // copy because PP will own the string.
PredefineBuffer.push_back(0);
- PP.setPredefines(&PredefineBuffer[0]);
+
+ char* predefines = new char[PredefineBuffer.size()];
+ std::copy(PredefineBuffer.begin(), PredefineBuffer.end(), predefines);
+ PP.setPredefines(predefines);
// Once we've read this, we're done.
return SourceMgr.getMainFileID();
@@ -1015,23 +1025,41 @@
namespace {
class VISIBILITY_HIDDEN DriverPreprocessorFactory : public PreprocessorFactory {
+ const std::string &InFile;
Diagnostic &Diags;
const LangOptions &LangInfo;
TargetInfo &Target;
SourceManager &SourceMgr;
HeaderSearch &HeaderInfo;
-
+ std::vector<char> PredefineBuffer;
+ bool InitializeSourceMgr;
+
public:
- DriverPreprocessorFactory(Diagnostic &diags, const LangOptions &opts,
+ DriverPreprocessorFactory(const std::string &infile,
+ Diagnostic &diags, const LangOptions &opts,
TargetInfo &target, SourceManager &SM,
HeaderSearch &Headers)
- : Diags(diags), LangInfo(opts), Target(target),
- SourceMgr(SM), HeaderInfo(Headers) {}
+ : InFile(infile), Diags(diags), LangInfo(opts), Target(target),
+ SourceMgr(SM), HeaderInfo(Headers), InitializeSourceMgr(true) {}
+
virtual ~DriverPreprocessorFactory() {}
virtual Preprocessor* CreatePreprocessor() {
- return new Preprocessor(Diags, LangInfo, Target, SourceMgr, HeaderInfo);
+ PredefineBuffer.clear();
+
+ Preprocessor* PP = new Preprocessor(Diags, LangInfo, Target,
+ SourceMgr, HeaderInfo);
+
+ if (!InitializePreprocessor(*PP, InitializeSourceMgr, InFile,
+ PredefineBuffer)) {
+ delete PP;
+ return NULL;
+ }
+
+ InitializeSourceMgr = false;
+
+ return PP;
}
};
}
@@ -1060,6 +1088,7 @@
Diagnostic& Diag, FileManager& FileMgr,
const LangOptions& LangOpts,
Preprocessor *PP,
+ PreprocessorFactory *PPF,
llvm::Module *&DestModule) {
switch (ProgAction) {
default:
@@ -1075,7 +1104,7 @@
return CreateASTViewer();
case EmitHTML:
- return CreateHTMLPrinter(OutputFile, Diag, PP);
+ return CreateHTMLPrinter(OutputFile, Diag, PP, PPF);
case ParseCFGDump:
case ParseCFGView:
@@ -1092,12 +1121,12 @@
return CreateUnitValsChecker(Diag);
case AnalysisGRSimpleVals:
- return CreateGRSimpleVals(Diag, PP, AnalyzeSpecificFunction, OutputFile,
- VisualizeEG, TrimGraph, AnalyzeAll);
+ return CreateGRSimpleVals(Diag, PP, PPF, AnalyzeSpecificFunction,
+ OutputFile, VisualizeEG, TrimGraph, AnalyzeAll);
case CheckerCFRef:
- return CreateCFRefChecker(Diag, PP, AnalyzeSpecificFunction, OutputFile,
- VisualizeEG, TrimGraph, AnalyzeAll);
+ return CreateCFRefChecker(Diag, PP, PPF, AnalyzeSpecificFunction,
+ OutputFile, VisualizeEG, TrimGraph, AnalyzeAll);
case TestSerialization:
return CreateSerializationTest(Diag, FileMgr, LangOpts);
@@ -1118,7 +1147,8 @@
/// ProcessInputFile - Process a single input file with the specified state.
///
-static void ProcessInputFile(Preprocessor &PP, const std::string &InFile) {
+static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF,
+ const std::string &InFile) {
ASTConsumer* Consumer = NULL;
bool ClearSourceMgr = false;
@@ -1128,7 +1158,7 @@
default:
Consumer = CreateASTConsumer(InFile, PP.getDiagnostics(),
PP.getFileManager(), PP.getLangOptions(), &PP,
- CodeGenModule);
+ &PPF, CodeGenModule);
if (!Consumer) {
fprintf(stderr, "Unexpected program action!\n");
@@ -1267,7 +1297,7 @@
// translation unit, rather than InFile.
llvm::Module *DestModule;
llvm::OwningPtr<ASTConsumer>
- Consumer(CreateASTConsumer(InFile, Diag, FileMgr, TU->getLangOpts(), 0,
+ Consumer(CreateASTConsumer(InFile, Diag, FileMgr, TU->getLangOpts(), 0, 0,
DestModule));
if (!Consumer) {
@@ -1320,7 +1350,7 @@
// FIXME: The HTMLDiagnosticClient uses the Preprocessor for
// (optional) syntax highlighting, but we don't have a preprocessor yet.
// Fix this dependency later.
- DiagClient.reset(CreateHTMLDiagnosticClient(HTMLDiag, NULL));
+ DiagClient.reset(CreateHTMLDiagnosticClient(HTMLDiag, 0, 0));
}
else { // Use Text diagnostics.
if (!VerifyDiagnostics) {
@@ -1387,16 +1417,15 @@
InitializeIncludePaths(argv[0], HeaderInfo, FileMgr, LangInfo);
// Set up the preprocessor with these options.
- DriverPreprocessorFactory PPFactory(Diags, LangInfo, *Target,
+ DriverPreprocessorFactory PPFactory(InFile, Diags, LangInfo, *Target,
SourceMgr, HeaderInfo);
llvm::OwningPtr<Preprocessor> PP(PPFactory.CreatePreprocessor());
- std::vector<char> PredefineBuffer;
- if (!InitializePreprocessor(*PP, InFile, PredefineBuffer))
+ if (!PP)
continue;
- ProcessInputFile(*PP, InFile);
+ ProcessInputFile(*PP, PPFactory, InFile);
HeaderInfo.ClearFileInfo();
if (Stats)