Implement "-include-pth" in low-level driver. This allows a PTH file to be used

similar to a regular file passed to "-include". When -include-pth is used, the
low-level driver queries the PTH file for the name of the original source file
that generated the PTH file and implicitly adds a '#include' for that file in
the Predefines buffer.

llvm-svn: 67352
This commit is contained in:
Ted Kremenek 2009-03-20 00:26:38 +00:00
parent 22c3dd4c1c
commit a1a0e4b27e
1 changed files with 42 additions and 4 deletions

View File

@ -834,6 +834,10 @@ static llvm::cl::list<std::string>
ImplicitIncludes("include", llvm::cl::value_desc("file"),
llvm::cl::desc("Include file before parsing"));
static llvm::cl::opt<std::string>
ImplicitIncludePTH("include-pth", llvm::cl::value_desc("file"),
llvm::cl::desc("Include file before parsing"));
// Append a #define line to Buf for Macro. Macro should be of the form XXX,
// in which case we emit "#define XXX 1" or "XXX=Y z W" in which case we emit
// "#define XXX Y z W". To get a #define with no value, use "XXX=".
@ -864,6 +868,23 @@ static void AddImplicitInclude(std::vector<char> &Buf, const std::string &File){
Buf.push_back('\n');
}
/// AddImplicitIncludePTH - Add an implicit #include using the original file
/// used to generate a PTH cache.
static void AddImplicitIncludePTH(std::vector<char> &Buf, Preprocessor & PP) {
PTHManager *P = PP.getPTHManager();
assert(P && "No PTHManager.");
const char *OriginalFile = P->getOriginalSourceFile();
if (!OriginalFile) {
assert(!ImplicitIncludePTH.empty());
fprintf(stderr, "error: PTH file '%s' does not designate an original "
"source header file for -include-pth\n",
ImplicitIncludePTH.c_str());
exit (1);
}
AddImplicitInclude(Buf, OriginalFile);
}
/// InitializePreprocessor - Initialize the preprocessor getting it and the
/// environment ready to process a single file. This returns true on error.
@ -910,9 +931,18 @@ static bool InitializePreprocessor(Preprocessor &PP,
// FIXME: Read any files specified by -imacros.
// Add implicit #includes from -include.
for (unsigned i = 0, e = ImplicitIncludes.size(); i != e; ++i)
// Add implicit #includes from -include and -include-pth.
bool handledPTH = ImplicitIncludePTH.empty();
for (unsigned i = 0, e = ImplicitIncludes.size(); i != e; ++i) {
if (!handledPTH) {
AddImplicitIncludePTH(PredefineBuffer, PP);
handledPTH = true;
}
AddImplicitInclude(PredefineBuffer, ImplicitIncludes[i]);
}
if (!handledPTH && !ImplicitIncludePTH.empty())
AddImplicitIncludePTH(PredefineBuffer, PP);
// Null terminate PredefinedBuffer and add it.
PredefineBuffer.push_back(0);
@ -1110,9 +1140,17 @@ public:
virtual Preprocessor* CreatePreprocessor() {
llvm::OwningPtr<PTHManager> PTHMgr;
if (!TokenCache.empty() && !ImplicitIncludePTH.empty()) {
fprintf(stderr, "error: cannot use both -token-cache and -include-pth "
"options\n");
exit (1);
}
// Use PTH?
if (!TokenCache.empty())
PTHMgr.reset(PTHManager::Create(TokenCache, &Diags));
if (!TokenCache.empty() || !ImplicitIncludePTH.empty()) {
const std::string& x = TokenCache.empty() ? ImplicitIncludePTH:TokenCache;
PTHMgr.reset(PTHManager::Create(x, &Diags));
}
// Create the Preprocessor.
llvm::OwningPtr<Preprocessor> PP(new Preprocessor(Diags, LangInfo, Target,