121473f7bSZachary Turner //===- PDBSymbolCompiland.cpp - compiland details --------*- C++ -*-===// 221473f7bSZachary Turner // 321473f7bSZachary Turner // The LLVM Compiler Infrastructure 421473f7bSZachary Turner // 521473f7bSZachary Turner // This file is distributed under the University of Illinois Open Source 621473f7bSZachary Turner // License. See LICENSE.TXT for details. 721473f7bSZachary Turner // 821473f7bSZachary Turner //===----------------------------------------------------------------------===// 921473f7bSZachary Turner 10*da611207SAaron Smith #include "llvm/DebugInfo/PDB/IPDBSession.h" 11*da611207SAaron Smith #include "llvm/DebugInfo/PDB/IPDBSourceFile.h" 12*da611207SAaron Smith 1352c9f881SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" 1443ec3af9SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h" 15*da611207SAaron Smith #include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h" 169a818ad1SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymDumper.h" 1752c9f881SZachary Turner 18*da611207SAaron Smith #include "llvm/ADT/StringSwitch.h" 19*da611207SAaron Smith #include "llvm/Support/Path.h" 2071f308adSChandler Carruth #include <utility> 2121473f7bSZachary Turner 2221473f7bSZachary Turner using namespace llvm; 23ec28fc34SZachary Turner using namespace llvm::pdb; 2421473f7bSZachary Turner 2598571ed9SZachary Turner PDBSymbolCompiland::PDBSymbolCompiland(const IPDBSession &PDBSession, 26bae16b3fSZachary Turner std::unique_ptr<IPDBRawSymbol> Symbol) 271b1a70f1SZachary Turner : PDBSymbol(PDBSession, std::move(Symbol)) { 281b1a70f1SZachary Turner assert(RawSymbol->getSymTag() == PDB_SymType::Compiland); 291b1a70f1SZachary Turner } 3021473f7bSZachary Turner 31b52d08d9SZachary Turner void PDBSymbolCompiland::dump(PDBSymDumper &Dumper) const { 32b52d08d9SZachary Turner Dumper.dump(*this); 3321473f7bSZachary Turner } 3443ec3af9SZachary Turner 35*da611207SAaron Smith std::string PDBSymbolCompiland::getSourceFileName() const { 36*da611207SAaron Smith return llvm::sys::path::filename(getSourceFileFullPath()).str(); 37*da611207SAaron Smith } 38*da611207SAaron Smith 39*da611207SAaron Smith std::string PDBSymbolCompiland::getSourceFileFullPath() const { 40*da611207SAaron Smith std::string SourceFileFullPath; 41*da611207SAaron Smith 42*da611207SAaron Smith // RecordedResult could be the basename, relative path or full path of the 43*da611207SAaron Smith // source file. Usually it is retrieved and recorded from the command that 44*da611207SAaron Smith // compiles this compiland. 45*da611207SAaron Smith // 46*da611207SAaron Smith // cmd FileName -> RecordedResult = .\\FileName 47*da611207SAaron Smith // cmd (Path)\\FileName -> RecordedResult = (Path)\\FileName 48*da611207SAaron Smith // 49*da611207SAaron Smith std::string RecordedResult = RawSymbol->getSourceFileName(); 50*da611207SAaron Smith 51*da611207SAaron Smith if (RecordedResult.empty()) { 52*da611207SAaron Smith if (auto Envs = findAllChildren<PDBSymbolCompilandEnv>()) { 53*da611207SAaron Smith std::string EnvWorkingDir, EnvSrc; 54*da611207SAaron Smith 5543ec3af9SZachary Turner while (auto Env = Envs->getNext()) { 5643ec3af9SZachary Turner std::string Var = Env->getName(); 57*da611207SAaron Smith if (Var == "cwd") { 58*da611207SAaron Smith EnvWorkingDir = Env->getValue(); 5943ec3af9SZachary Turner continue; 6043ec3af9SZachary Turner } 61*da611207SAaron Smith if (Var == "src") { 62*da611207SAaron Smith EnvSrc = Env->getValue(); 63*da611207SAaron Smith if (llvm::sys::path::is_absolute(EnvSrc)) 64*da611207SAaron Smith return EnvSrc; 65*da611207SAaron Smith RecordedResult = EnvSrc; 66*da611207SAaron Smith continue; 67*da611207SAaron Smith } 68*da611207SAaron Smith } 69*da611207SAaron Smith if (!EnvWorkingDir.empty() && !EnvSrc.empty()) { 70*da611207SAaron Smith auto Len = EnvWorkingDir.length(); 71*da611207SAaron Smith if (EnvWorkingDir[Len - 1] != '/' && EnvWorkingDir[Len - 1] != '\\') { 72*da611207SAaron Smith std::string Path = EnvWorkingDir + "\\" + EnvSrc; 73*da611207SAaron Smith std::replace(Path.begin(), Path.end(), '/', '\\'); 74*da611207SAaron Smith // We will return it as full path if we can't find a better one. 75*da611207SAaron Smith if (llvm::sys::path::is_absolute(Path)) 76*da611207SAaron Smith SourceFileFullPath = Path; 77*da611207SAaron Smith } 78*da611207SAaron Smith } 79*da611207SAaron Smith } 80*da611207SAaron Smith } 81*da611207SAaron Smith 82*da611207SAaron Smith if (!RecordedResult.empty()) { 83*da611207SAaron Smith if (llvm::sys::path::is_absolute(RecordedResult)) 84*da611207SAaron Smith return RecordedResult; 85*da611207SAaron Smith 86*da611207SAaron Smith // This searches name that has same basename as the one in RecordedResult. 87*da611207SAaron Smith auto OneSrcFile = 88*da611207SAaron Smith Session.findOneSourceFile(this, RecordedResult, 89*da611207SAaron Smith PDB_NameSearchFlags::NS_CaseInsensitive); 90*da611207SAaron Smith if (OneSrcFile) 91*da611207SAaron Smith return OneSrcFile->getFileName(); 92*da611207SAaron Smith } 93*da611207SAaron Smith 94*da611207SAaron Smith // At this point, we have to walk through all source files of this compiland, 95*da611207SAaron Smith // and determine the right source file if any that is used to generate this 96*da611207SAaron Smith // compiland based on language indicated in compilanddetails language field. 97*da611207SAaron Smith auto Details = findOneChild<PDBSymbolCompilandDetails>(); 98*da611207SAaron Smith PDB_Lang Lang = Details ? Details->getLanguage() : PDB_Lang::Cpp; 99*da611207SAaron Smith auto SrcFiles = Session.getSourceFilesForCompiland(*this); 100*da611207SAaron Smith if (SrcFiles) { 101*da611207SAaron Smith bool LangC = (Lang == PDB_Lang::Cpp || Lang == PDB_Lang::C); 102*da611207SAaron Smith while (auto File = SrcFiles->getNext()) { 103*da611207SAaron Smith std::string FileName = File->getFileName(); 104*da611207SAaron Smith auto file_extension = llvm::sys::path::extension(FileName); 105*da611207SAaron Smith if (StringSwitch<bool>(file_extension.lower()) 106*da611207SAaron Smith .Case(".cpp", LangC) 107*da611207SAaron Smith .Case(".c", LangC) 108*da611207SAaron Smith .Case(".cc", LangC) 109*da611207SAaron Smith .Case(".cxx", LangC) 110*da611207SAaron Smith .Case(".asm", Lang == PDB_Lang::Masm) 111*da611207SAaron Smith .Default(false)) 112*da611207SAaron Smith return File->getFileName(); 113*da611207SAaron Smith } 114*da611207SAaron Smith } 115*da611207SAaron Smith 116*da611207SAaron Smith return SourceFileFullPath; 11743ec3af9SZachary Turner } 118