1*c0a5c01aSAaron Smith //===- 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 10da611207SAaron Smith #include "llvm/DebugInfo/PDB/IPDBSession.h" 11da611207SAaron Smith #include "llvm/DebugInfo/PDB/IPDBSourceFile.h" 12da611207SAaron Smith 1352c9f881SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" 14da611207SAaron Smith #include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h" 15*c0a5c01aSAaron Smith #include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h" 169a818ad1SZachary Turner #include "llvm/DebugInfo/PDB/PDBSymDumper.h" 1752c9f881SZachary Turner 18da611207SAaron Smith #include "llvm/ADT/StringSwitch.h" 19da611207SAaron 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 35da611207SAaron Smith std::string PDBSymbolCompiland::getSourceFileName() const { 36*c0a5c01aSAaron Smith return sys::path::filename(getSourceFileFullPath()).str(); 37da611207SAaron Smith } 38da611207SAaron Smith 39da611207SAaron Smith std::string PDBSymbolCompiland::getSourceFileFullPath() const { 40da611207SAaron Smith std::string SourceFileFullPath; 41da611207SAaron Smith 42da611207SAaron Smith // RecordedResult could be the basename, relative path or full path of the 43da611207SAaron Smith // source file. Usually it is retrieved and recorded from the command that 44da611207SAaron Smith // compiles this compiland. 45da611207SAaron Smith // 46da611207SAaron Smith // cmd FileName -> RecordedResult = .\\FileName 47da611207SAaron Smith // cmd (Path)\\FileName -> RecordedResult = (Path)\\FileName 48da611207SAaron Smith // 49da611207SAaron Smith std::string RecordedResult = RawSymbol->getSourceFileName(); 50da611207SAaron Smith 51da611207SAaron Smith if (RecordedResult.empty()) { 52da611207SAaron Smith if (auto Envs = findAllChildren<PDBSymbolCompilandEnv>()) { 53da611207SAaron Smith std::string EnvWorkingDir, EnvSrc; 54da611207SAaron Smith 5543ec3af9SZachary Turner while (auto Env = Envs->getNext()) { 5643ec3af9SZachary Turner std::string Var = Env->getName(); 57da611207SAaron Smith if (Var == "cwd") { 58da611207SAaron Smith EnvWorkingDir = Env->getValue(); 5943ec3af9SZachary Turner continue; 6043ec3af9SZachary Turner } 61da611207SAaron Smith if (Var == "src") { 62da611207SAaron Smith EnvSrc = Env->getValue(); 63*c0a5c01aSAaron Smith if (sys::path::is_absolute(EnvSrc)) 64da611207SAaron Smith return EnvSrc; 65da611207SAaron Smith RecordedResult = EnvSrc; 66da611207SAaron Smith continue; 67da611207SAaron Smith } 68da611207SAaron Smith } 69da611207SAaron Smith if (!EnvWorkingDir.empty() && !EnvSrc.empty()) { 70da611207SAaron Smith auto Len = EnvWorkingDir.length(); 71da611207SAaron Smith if (EnvWorkingDir[Len - 1] != '/' && EnvWorkingDir[Len - 1] != '\\') { 72da611207SAaron Smith std::string Path = EnvWorkingDir + "\\" + EnvSrc; 73da611207SAaron Smith std::replace(Path.begin(), Path.end(), '/', '\\'); 74da611207SAaron Smith // We will return it as full path if we can't find a better one. 75*c0a5c01aSAaron Smith if (sys::path::is_absolute(Path)) 76da611207SAaron Smith SourceFileFullPath = Path; 77da611207SAaron Smith } 78da611207SAaron Smith } 79da611207SAaron Smith } 80da611207SAaron Smith } 81da611207SAaron Smith 82da611207SAaron Smith if (!RecordedResult.empty()) { 83*c0a5c01aSAaron Smith if (sys::path::is_absolute(RecordedResult)) 84da611207SAaron Smith return RecordedResult; 85da611207SAaron Smith 86da611207SAaron Smith // This searches name that has same basename as the one in RecordedResult. 87*c0a5c01aSAaron Smith auto OneSrcFile = Session.findOneSourceFile( 88*c0a5c01aSAaron Smith this, RecordedResult, PDB_NameSearchFlags::NS_CaseInsensitive); 89da611207SAaron Smith if (OneSrcFile) 90da611207SAaron Smith return OneSrcFile->getFileName(); 91da611207SAaron Smith } 92da611207SAaron Smith 93da611207SAaron Smith // At this point, we have to walk through all source files of this compiland, 94da611207SAaron Smith // and determine the right source file if any that is used to generate this 95da611207SAaron Smith // compiland based on language indicated in compilanddetails language field. 96da611207SAaron Smith auto Details = findOneChild<PDBSymbolCompilandDetails>(); 97da611207SAaron Smith PDB_Lang Lang = Details ? Details->getLanguage() : PDB_Lang::Cpp; 98da611207SAaron Smith auto SrcFiles = Session.getSourceFilesForCompiland(*this); 99da611207SAaron Smith if (SrcFiles) { 100da611207SAaron Smith bool LangC = (Lang == PDB_Lang::Cpp || Lang == PDB_Lang::C); 101da611207SAaron Smith while (auto File = SrcFiles->getNext()) { 102da611207SAaron Smith std::string FileName = File->getFileName(); 103*c0a5c01aSAaron Smith auto file_extension = sys::path::extension(FileName); 104da611207SAaron Smith if (StringSwitch<bool>(file_extension.lower()) 105da611207SAaron Smith .Case(".cpp", LangC) 106da611207SAaron Smith .Case(".c", LangC) 107da611207SAaron Smith .Case(".cc", LangC) 108da611207SAaron Smith .Case(".cxx", LangC) 109da611207SAaron Smith .Case(".asm", Lang == PDB_Lang::Masm) 110da611207SAaron Smith .Default(false)) 111da611207SAaron Smith return File->getFileName(); 112da611207SAaron Smith } 113da611207SAaron Smith } 114da611207SAaron Smith 115da611207SAaron Smith return SourceFileFullPath; 11643ec3af9SZachary Turner } 117