1750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar//===--- DependencyFile.cpp - Generate dependency file --------------------===// 2750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar// 3750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar// The LLVM Compiler Infrastructure 4750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar// 5750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar// This file is distributed under the University of Illinois Open Source 6750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar// License. See LICENSE.TXT for details. 7750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar// 8750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar//===----------------------------------------------------------------------===// 9750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar// 10750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar// This code generates dependency files. 11750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar// 12750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar//===----------------------------------------------------------------------===// 13750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar 14b09f6e15c59b89d5820db8ef40598eb1d1323c1fEli Friedman#include "clang/Frontend/Utils.h" 15b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner#include "clang/Basic/FileManager.h" 160e0bae8139e25de81f18b6a519783a06f7ba1e25Daniel Dunbar#include "clang/Basic/SourceManager.h" 170e0bae8139e25de81f18b6a519783a06f7ba1e25Daniel Dunbar#include "clang/Frontend/DependencyOutputOptions.h" 180e0bae8139e25de81f18b6a519783a06f7ba1e25Daniel Dunbar#include "clang/Frontend/FrontendDiagnostic.h" 190e0bae8139e25de81f18b6a519783a06f7ba1e25Daniel Dunbar#include "clang/Lex/DirectoryLookup.h" 20bb52786da8d055568eef6e5694288c1258bc8c2aPeter Collingbourne#include "clang/Lex/LexDiagnostic.h" 210e0bae8139e25de81f18b6a519783a06f7ba1e25Daniel Dunbar#include "clang/Lex/PPCallbacks.h" 220e0bae8139e25de81f18b6a519783a06f7ba1e25Daniel Dunbar#include "clang/Lex/Preprocessor.h" 23651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/Serialization/ASTReader.h" 24750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar#include "llvm/ADT/StringSet.h" 250b214905f7fff7fa21ecc54a17b97372ba0c9a07Benjamin Kramer#include "llvm/Support/FileSystem.h" 26a6e023c4491a8a8116c11783f4e81c7bd172f88dEli Friedman#include "llvm/Support/Path.h" 277e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar#include "llvm/Support/raw_ostream.h" 28750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar 29750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbarusing namespace clang; 30750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar 31750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbarnamespace { 32ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesstruct DepCollectorPPCallbacks : public PPCallbacks { 33ef8225444452a1486bd721f3285301fe84643b00Stephen Hines DependencyCollector &DepCollector; 34ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SourceManager &SM; 35ef8225444452a1486bd721f3285301fe84643b00Stephen Hines DepCollectorPPCallbacks(DependencyCollector &L, SourceManager &SM) 36ef8225444452a1486bd721f3285301fe84643b00Stephen Hines : DepCollector(L), SM(SM) { } 37ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 38ef8225444452a1486bd721f3285301fe84643b00Stephen Hines void FileChanged(SourceLocation Loc, FileChangeReason Reason, 39ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SrcMgr::CharacteristicKind FileType, 40ef8225444452a1486bd721f3285301fe84643b00Stephen Hines FileID PrevFID) override { 41ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (Reason != PPCallbacks::EnterFile) 42ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return; 43ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 44ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // Dependency generation really does want to go all the way to the 45ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // file entry for a source location to find out what is depended on. 46ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // We do not want #line markers to affect dependency generation! 47ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const FileEntry *FE = 48ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SM.getFileEntryForID(SM.getFileID(SM.getExpansionLoc(Loc))); 49ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (!FE) 50ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return; 51ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 52ef8225444452a1486bd721f3285301fe84643b00Stephen Hines StringRef Filename = FE->getName(); 53ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 54ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // Remove leading "./" (or ".//" or "././" etc.) 55ef8225444452a1486bd721f3285301fe84643b00Stephen Hines while (Filename.size() > 2 && Filename[0] == '.' && 56ef8225444452a1486bd721f3285301fe84643b00Stephen Hines llvm::sys::path::is_separator(Filename[1])) { 57ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Filename = Filename.substr(1); 58ef8225444452a1486bd721f3285301fe84643b00Stephen Hines while (llvm::sys::path::is_separator(Filename[0])) 59ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Filename = Filename.substr(1); 60ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 61ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 62ef8225444452a1486bd721f3285301fe84643b00Stephen Hines DepCollector.maybeAddDependency(Filename, /*FromModule*/false, 63ef8225444452a1486bd721f3285301fe84643b00Stephen Hines FileType != SrcMgr::C_User, 64ef8225444452a1486bd721f3285301fe84643b00Stephen Hines /*IsModuleFile*/false, /*IsMissing*/false); 65ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 66ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 67ef8225444452a1486bd721f3285301fe84643b00Stephen Hines void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, 68ef8225444452a1486bd721f3285301fe84643b00Stephen Hines StringRef FileName, bool IsAngled, 69ef8225444452a1486bd721f3285301fe84643b00Stephen Hines CharSourceRange FilenameRange, const FileEntry *File, 70ef8225444452a1486bd721f3285301fe84643b00Stephen Hines StringRef SearchPath, StringRef RelativePath, 71ef8225444452a1486bd721f3285301fe84643b00Stephen Hines const Module *Imported) override { 72ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (!File) 73ef8225444452a1486bd721f3285301fe84643b00Stephen Hines DepCollector.maybeAddDependency(FileName, /*FromModule*/false, 74ef8225444452a1486bd721f3285301fe84643b00Stephen Hines /*IsSystem*/false, /*IsModuleFile*/false, 75ef8225444452a1486bd721f3285301fe84643b00Stephen Hines /*IsMissing*/true); 76ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // Files that actually exist are handled by FileChanged. 77ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 78ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 79ef8225444452a1486bd721f3285301fe84643b00Stephen Hines void EndOfMainFile() override { 80ef8225444452a1486bd721f3285301fe84643b00Stephen Hines DepCollector.finishedMainFile(); 81ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 82ef8225444452a1486bd721f3285301fe84643b00Stephen Hines}; 83ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 84ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesstruct DepCollectorASTListener : public ASTReaderListener { 85ef8225444452a1486bd721f3285301fe84643b00Stephen Hines DependencyCollector &DepCollector; 86ef8225444452a1486bd721f3285301fe84643b00Stephen Hines DepCollectorASTListener(DependencyCollector &L) : DepCollector(L) { } 87ef8225444452a1486bd721f3285301fe84643b00Stephen Hines bool needsInputFileVisitation() override { return true; } 88ef8225444452a1486bd721f3285301fe84643b00Stephen Hines bool needsSystemInputFileVisitation() override { 89ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return DepCollector.needSystemDependencies(); 90ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 91ef8225444452a1486bd721f3285301fe84643b00Stephen Hines void visitModuleFile(StringRef Filename) override { 92ef8225444452a1486bd721f3285301fe84643b00Stephen Hines DepCollector.maybeAddDependency(Filename, /*FromModule*/true, 93ef8225444452a1486bd721f3285301fe84643b00Stephen Hines /*IsSystem*/false, /*IsModuleFile*/true, 94ef8225444452a1486bd721f3285301fe84643b00Stephen Hines /*IsMissing*/false); 95ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 96ef8225444452a1486bd721f3285301fe84643b00Stephen Hines bool visitInputFile(StringRef Filename, bool IsSystem, 97ef8225444452a1486bd721f3285301fe84643b00Stephen Hines bool IsOverridden) override { 98ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (IsOverridden) 99ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return true; 100ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 101ef8225444452a1486bd721f3285301fe84643b00Stephen Hines DepCollector.maybeAddDependency(Filename, /*FromModule*/true, IsSystem, 102ef8225444452a1486bd721f3285301fe84643b00Stephen Hines /*IsModuleFile*/false, /*IsMissing*/false); 103ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return true; 104ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 105ef8225444452a1486bd721f3285301fe84643b00Stephen Hines}; 106ef8225444452a1486bd721f3285301fe84643b00Stephen Hines} // end anonymous namespace 107ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 108ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesvoid DependencyCollector::maybeAddDependency(StringRef Filename, bool FromModule, 109ef8225444452a1486bd721f3285301fe84643b00Stephen Hines bool IsSystem, bool IsModuleFile, 110ef8225444452a1486bd721f3285301fe84643b00Stephen Hines bool IsMissing) { 111ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (Seen.insert(Filename) && 112ef8225444452a1486bd721f3285301fe84643b00Stephen Hines sawDependency(Filename, FromModule, IsSystem, IsModuleFile, IsMissing)) 113ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Dependencies.push_back(Filename); 114ef8225444452a1486bd721f3285301fe84643b00Stephen Hines} 115ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 116ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesbool DependencyCollector::sawDependency(StringRef Filename, bool FromModule, 117ef8225444452a1486bd721f3285301fe84643b00Stephen Hines bool IsSystem, bool IsModuleFile, 118ef8225444452a1486bd721f3285301fe84643b00Stephen Hines bool IsMissing) { 119ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return Filename != "<built-in>" && (needSystemDependencies() || !IsSystem); 120ef8225444452a1486bd721f3285301fe84643b00Stephen Hines} 121ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 122ef8225444452a1486bd721f3285301fe84643b00Stephen HinesDependencyCollector::~DependencyCollector() { } 123ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesvoid DependencyCollector::attachToPreprocessor(Preprocessor &PP) { 124ef8225444452a1486bd721f3285301fe84643b00Stephen Hines PP.addPPCallbacks(new DepCollectorPPCallbacks(*this, PP.getSourceManager())); 125ef8225444452a1486bd721f3285301fe84643b00Stephen Hines} 126ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesvoid DependencyCollector::attachToASTReader(ASTReader &R) { 127ef8225444452a1486bd721f3285301fe84643b00Stephen Hines R.addListener(new DepCollectorASTListener(*this)); 128ef8225444452a1486bd721f3285301fe84643b00Stephen Hines} 129ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 130ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesnamespace { 131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// Private implementation for DependencyFileGenerator 132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass DFGImpl : public PPCallbacks { 1337e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar std::vector<std::string> Files; 1347e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar llvm::StringSet<> FilesSet; 135750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar const Preprocessor *PP; 1361b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne std::string OutputFile; 13702fbb2578538e93f901f75fdc7d278c4c0e935deChris Lattner std::vector<std::string> Targets; 138b5c8f8bddc6007b154b5c40640c4f80e7cb0a6ebEli Friedman bool IncludeSystemHeaders; 139b5c8f8bddc6007b154b5c40640c4f80e7cb0a6ebEli Friedman bool PhonyTarget; 140bb52786da8d055568eef6e5694288c1258bc8c2aPeter Collingbourne bool AddMissingHeaderDeps; 1411b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne bool SeenMissingHeader; 142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool IncludeModuleFiles; 143750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbarprivate: 144750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar bool FileMatchesDepCriteria(const char *Filename, 1459d72851fec9e9c62570a027d42701562bbf29751Chris Lattner SrcMgr::CharacteristicKind FileType); 146750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar void OutputDependencyFile(); 147750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar 148750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbarpublic: 149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DFGImpl(const Preprocessor *_PP, const DependencyOutputOptions &Opts) 1501b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne : PP(_PP), OutputFile(Opts.OutputFile), Targets(Opts.Targets), 1510e0bae8139e25de81f18b6a519783a06f7ba1e25Daniel Dunbar IncludeSystemHeaders(Opts.IncludeSystemHeaders), 152bb52786da8d055568eef6e5694288c1258bc8c2aPeter Collingbourne PhonyTarget(Opts.UsePhonyTargets), 1531b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne AddMissingHeaderDeps(Opts.AddMissingHeaderDeps), 154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SeenMissingHeader(false), 155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines IncludeModuleFiles(Opts.IncludeModuleFiles) {} 156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void FileChanged(SourceLocation Loc, FileChangeReason Reason, 158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SrcMgr::CharacteristicKind FileType, 159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FileID PrevFID) override; 160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, 161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef FileName, bool IsAngled, 162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CharSourceRange FilenameRange, const FileEntry *File, 163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef SearchPath, StringRef RelativePath, 164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Module *Imported) override; 165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void EndOfMainFile() override { 167a5a7bd0de7b6b80212095195a055a4a43f21d4b2Daniel Dunbar OutputDependencyFile(); 168a5a7bd0de7b6b80212095195a055a4a43f21d4b2Daniel Dunbar } 169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void AddFilename(StringRef Filename); 171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool includeSystemHeaders() const { return IncludeSystemHeaders; } 172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool includeModuleFiles() const { return IncludeModuleFiles; } 173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass DFGASTReaderListener : public ASTReaderListener { 176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DFGImpl &Parent; 177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic: 178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DFGASTReaderListener(DFGImpl &Parent) 179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : Parent(Parent) { } 180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool needsInputFileVisitation() override { return true; } 181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool needsSystemInputFileVisitation() override { 182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Parent.includeSystemHeaders(); 183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void visitModuleFile(StringRef Filename) override; 185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool visitInputFile(StringRef Filename, bool isSystem, 186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isOverridden) override; 187750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar}; 188750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar} 189750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar 190651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesDependencyFileGenerator::DependencyFileGenerator(void *Impl) 191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines: Impl(Impl) { } 192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 193651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesDependencyFileGenerator *DependencyFileGenerator::CreateAndAttachToPreprocessor( 194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines clang::Preprocessor &PP, const clang::DependencyOutputOptions &Opts) { 195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1960e0bae8139e25de81f18b6a519783a06f7ba1e25Daniel Dunbar if (Opts.Targets.empty()) { 197ca11f61233b2acc266f371816e48290af4e10528Daniel Dunbar PP.getDiagnostics().Report(diag::err_fe_dependency_file_requires_MT); 1986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 1990e0bae8139e25de81f18b6a519783a06f7ba1e25Daniel Dunbar } 200750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar 201bb52786da8d055568eef6e5694288c1258bc8c2aPeter Collingbourne // Disable the "file not found" diagnostic if the -MG option was given. 202f84139a1331c63c998e8b7d54148c75ac0b48ccdEli Friedman if (Opts.AddMissingHeaderDeps) 203f84139a1331c63c998e8b7d54148c75ac0b48ccdEli Friedman PP.SetSuppressIncludeNotFoundError(true); 204bb52786da8d055568eef6e5694288c1258bc8c2aPeter Collingbourne 205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DFGImpl *Callback = new DFGImpl(&PP, Opts); 206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PP.addPPCallbacks(Callback); // PP owns the Callback 207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return new DependencyFileGenerator(Callback); 208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid DependencyFileGenerator::AttachToASTReader(ASTReader &R) { 211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DFGImpl *I = reinterpret_cast<DFGImpl *>(Impl); 212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(I && "missing implementation"); 213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines R.addListener(new DFGASTReaderListener(*I)); 214750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar} 215750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar 216750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar/// FileMatchesDepCriteria - Determine whether the given Filename should be 217750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar/// considered as a dependency. 218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesbool DFGImpl::FileMatchesDepCriteria(const char *Filename, 219651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SrcMgr::CharacteristicKind FileType) { 220a5a7bd0de7b6b80212095195a055a4a43f21d4b2Daniel Dunbar if (strcmp("<built-in>", Filename) == 0) 221a5a7bd0de7b6b80212095195a055a4a43f21d4b2Daniel Dunbar return false; 222a5a7bd0de7b6b80212095195a055a4a43f21d4b2Daniel Dunbar 223b5c8f8bddc6007b154b5c40640c4f80e7cb0a6ebEli Friedman if (IncludeSystemHeaders) 224a5a7bd0de7b6b80212095195a055a4a43f21d4b2Daniel Dunbar return true; 225750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar 226a5a7bd0de7b6b80212095195a055a4a43f21d4b2Daniel Dunbar return FileType == SrcMgr::C_User; 227750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar} 228750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar 229651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid DFGImpl::FileChanged(SourceLocation Loc, 230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FileChangeReason Reason, 231651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SrcMgr::CharacteristicKind FileType, 232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FileID PrevFID) { 233750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar if (Reason != PPCallbacks::EnterFile) 234750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar return; 2351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 236a5a7bd0de7b6b80212095195a055a4a43f21d4b2Daniel Dunbar // Dependency generation really does want to go all the way to the 237a5a7bd0de7b6b80212095195a055a4a43f21d4b2Daniel Dunbar // file entry for a source location to find out what is depended on. 238a5a7bd0de7b6b80212095195a055a4a43f21d4b2Daniel Dunbar // We do not want #line markers to affect dependency generation! 239b9c3f966b103f7cfe8e5e60007c4c8b38f7298ebChris Lattner SourceManager &SM = PP->getSourceManager(); 2401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 241e86e4cd097f50ca1c0bfde9142e0460d0d1203dbChris Lattner const FileEntry *FE = 242402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth SM.getFileEntryForID(SM.getFileID(SM.getExpansionLoc(Loc))); 2436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!FE) return; 2441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2455f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Filename = FE->getName(); 246a6e023c4491a8a8116c11783f4e81c7bd172f88dEli Friedman if (!FileMatchesDepCriteria(Filename.data(), FileType)) 247750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar return; 248750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar 249a6e023c4491a8a8116c11783f4e81c7bd172f88dEli Friedman // Remove leading "./" (or ".//" or "././" etc.) 250a6e023c4491a8a8116c11783f4e81c7bd172f88dEli Friedman while (Filename.size() > 2 && Filename[0] == '.' && 251a6e023c4491a8a8116c11783f4e81c7bd172f88dEli Friedman llvm::sys::path::is_separator(Filename[1])) { 252a6e023c4491a8a8116c11783f4e81c7bd172f88dEli Friedman Filename = Filename.substr(1); 253a6e023c4491a8a8116c11783f4e81c7bd172f88dEli Friedman while (llvm::sys::path::is_separator(Filename[0])) 254a6e023c4491a8a8116c11783f4e81c7bd172f88dEli Friedman Filename = Filename.substr(1); 255a6e023c4491a8a8116c11783f4e81c7bd172f88dEli Friedman } 256a6e023c4491a8a8116c11783f4e81c7bd172f88dEli Friedman 257bb52786da8d055568eef6e5694288c1258bc8c2aPeter Collingbourne AddFilename(Filename); 258bb52786da8d055568eef6e5694288c1258bc8c2aPeter Collingbourne} 259bb52786da8d055568eef6e5694288c1258bc8c2aPeter Collingbourne 260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid DFGImpl::InclusionDirective(SourceLocation HashLoc, 261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Token &IncludeTok, 262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef FileName, 263651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool IsAngled, 264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CharSourceRange FilenameRange, 265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const FileEntry *File, 266651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef SearchPath, 267651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef RelativePath, 268651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const Module *Imported) { 2691b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne if (!File) { 2701b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne if (AddMissingHeaderDeps) 2711b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne AddFilename(FileName); 2721b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne else 2731b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne SeenMissingHeader = true; 2741b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne } 275bb52786da8d055568eef6e5694288c1258bc8c2aPeter Collingbourne} 276750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar 277651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid DFGImpl::AddFilename(StringRef Filename) { 2787e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar if (FilesSet.insert(Filename)) 2797e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar Files.push_back(Filename); 280750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar} 281750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar 282ddc15c40d22718d7b7060634b782d1a3ce9184a8Benjamin Kramer/// PrintFilename - GCC escapes spaces, # and $, but apparently not ' or " or 283ddc15c40d22718d7b7060634b782d1a3ce9184a8Benjamin Kramer/// other scary characters. 2845f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic void PrintFilename(raw_ostream &OS, StringRef Filename) { 2859d50634cfc268ecc9a7250226dd5ca0e945240d4Chris Lattner for (unsigned i = 0, e = Filename.size(); i != e; ++i) { 286ddc15c40d22718d7b7060634b782d1a3ce9184a8Benjamin Kramer if (Filename[i] == ' ' || Filename[i] == '#') 2879d50634cfc268ecc9a7250226dd5ca0e945240d4Chris Lattner OS << '\\'; 288ddc15c40d22718d7b7060634b782d1a3ce9184a8Benjamin Kramer else if (Filename[i] == '$') // $ is escaped by $$. 289ddc15c40d22718d7b7060634b782d1a3ce9184a8Benjamin Kramer OS << '$'; 2909d50634cfc268ecc9a7250226dd5ca0e945240d4Chris Lattner OS << Filename[i]; 2919d50634cfc268ecc9a7250226dd5ca0e945240d4Chris Lattner } 2929d50634cfc268ecc9a7250226dd5ca0e945240d4Chris Lattner} 2939d50634cfc268ecc9a7250226dd5ca0e945240d4Chris Lattner 294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid DFGImpl::OutputDependencyFile() { 2951b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne if (SeenMissingHeader) { 296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::sys::fs::remove(OutputFile); 2971b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne return; 2981b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne } 2991b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne 3001b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne std::string Err; 301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::raw_fd_ostream OS(OutputFile.c_str(), Err, llvm::sys::fs::F_Text); 3021b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne if (!Err.empty()) { 3031b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne PP->getDiagnostics().Report(diag::err_fe_error_opening) 3041b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne << OutputFile << Err; 3051b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne return; 3061b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne } 3071b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne 3087e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar // Write out the dependency targets, trying to avoid overly long 3097e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar // lines when possible. We try our best to emit exactly the same 3107e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar // dependency file as GCC (4.2), assuming the included files are the 3117e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar // same. 3127e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar const unsigned MaxColumns = 75; 31302fbb2578538e93f901f75fdc7d278c4c0e935deChris Lattner unsigned Columns = 0; 31402fbb2578538e93f901f75fdc7d278c4c0e935deChris Lattner 31502fbb2578538e93f901f75fdc7d278c4c0e935deChris Lattner for (std::vector<std::string>::iterator 31602fbb2578538e93f901f75fdc7d278c4c0e935deChris Lattner I = Targets.begin(), E = Targets.end(); I != E; ++I) { 31702fbb2578538e93f901f75fdc7d278c4c0e935deChris Lattner unsigned N = I->length(); 31802fbb2578538e93f901f75fdc7d278c4c0e935deChris Lattner if (Columns == 0) { 31902fbb2578538e93f901f75fdc7d278c4c0e935deChris Lattner Columns += N; 32002fbb2578538e93f901f75fdc7d278c4c0e935deChris Lattner } else if (Columns + N + 2 > MaxColumns) { 32102fbb2578538e93f901f75fdc7d278c4c0e935deChris Lattner Columns = N + 2; 3221b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne OS << " \\\n "; 32302fbb2578538e93f901f75fdc7d278c4c0e935deChris Lattner } else { 32402fbb2578538e93f901f75fdc7d278c4c0e935deChris Lattner Columns += N + 1; 3251b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne OS << ' '; 32602fbb2578538e93f901f75fdc7d278c4c0e935deChris Lattner } 3279d50634cfc268ecc9a7250226dd5ca0e945240d4Chris Lattner // Targets already quoted as needed. 3281b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne OS << *I; 32902fbb2578538e93f901f75fdc7d278c4c0e935deChris Lattner } 33002fbb2578538e93f901f75fdc7d278c4c0e935deChris Lattner 3311b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne OS << ':'; 33202fbb2578538e93f901f75fdc7d278c4c0e935deChris Lattner Columns += 1; 3331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3347e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar // Now add each dependency in the order it was seen, but avoiding 3357e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar // duplicates. 3367e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar for (std::vector<std::string>::iterator I = Files.begin(), 3377e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar E = Files.end(); I != E; ++I) { 3387e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar // Start a new line if this would exceed the column limit. Make 3397e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar // sure to leave space for a trailing " \" in case we need to 3407e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar // break the line on the next iteration. 3417e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar unsigned N = I->length(); 3427e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar if (Columns + (N + 1) + 2 > MaxColumns) { 3431b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne OS << " \\\n "; 3447e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar Columns = 2; 3457e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar } 3461b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne OS << ' '; 3471b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne PrintFilename(OS, *I); 3487e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar Columns += N + 1; 3497e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar } 3501b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne OS << '\n'; 3517e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar 3527e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar // Create phony targets if requested. 353ccad3db9b95012e260c71ded41c6141619202b09Fariborz Jahanian if (PhonyTarget && !Files.empty()) { 3547e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar // Skip the first entry, this is always the input file itself. 3557e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar for (std::vector<std::string>::iterator I = Files.begin() + 1, 3567e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar E = Files.end(); I != E; ++I) { 3571b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne OS << '\n'; 3581b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne PrintFilename(OS, *I); 3591b91ab467cffd44c222f1c5bed76910cce059a9ePeter Collingbourne OS << ":\n"; 3607e9f1f7de84e6876e581980ec122d688fcfe1f31Daniel Dunbar } 361750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar } 362750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar} 363750c358049a0e91fd71a8d10a9ac8299c943e238Daniel Dunbar 364651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesbool DFGASTReaderListener::visitInputFile(llvm::StringRef Filename, 365651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool IsSystem, bool IsOverridden) { 366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(!IsSystem || needsSystemInputFileVisitation()); 367651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (IsOverridden) 368651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 369651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 370651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Parent.AddFilename(Filename); 371651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 372651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 373651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 374651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid DFGASTReaderListener::visitModuleFile(llvm::StringRef Filename) { 375651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Parent.includeModuleFiles()) 376651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Parent.AddFilename(Filename); 377651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 378