]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / DebugInfo / PDB / PDBSymbolCompiland.cpp
1 //===- PDBSymbolCompiland.cpp - compiland details ---------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/DebugInfo/PDB/IPDBSession.h"
11 #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
12
13 #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
14 #include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
15 #include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h"
16 #include "llvm/DebugInfo/PDB/PDBSymDumper.h"
17
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/Support/Path.h"
20 #include <utility>
21
22 using namespace llvm;
23 using namespace llvm::pdb;
24
25 PDBSymbolCompiland::PDBSymbolCompiland(const IPDBSession &PDBSession,
26                                        std::unique_ptr<IPDBRawSymbol> Symbol)
27     : PDBSymbol(PDBSession, std::move(Symbol)) {
28   assert(RawSymbol->getSymTag() == PDB_SymType::Compiland);
29 }
30
31 void PDBSymbolCompiland::dump(PDBSymDumper &Dumper) const {
32   Dumper.dump(*this);
33 }
34
35 std::string PDBSymbolCompiland::getSourceFileName() const {
36   return sys::path::filename(getSourceFileFullPath()).str();
37 }
38
39 std::string PDBSymbolCompiland::getSourceFileFullPath() const {
40   std::string SourceFileFullPath;
41
42   // RecordedResult could be the basename, relative path or full path of the
43   // source file. Usually it is retrieved and recorded from the command that
44   // compiles this compiland.
45   //
46   //  cmd FileName          -> RecordedResult = .\\FileName
47   //  cmd (Path)\\FileName  -> RecordedResult = (Path)\\FileName
48   //
49   std::string RecordedResult = RawSymbol->getSourceFileName();
50
51   if (RecordedResult.empty()) {
52     if (auto Envs = findAllChildren<PDBSymbolCompilandEnv>()) {
53       std::string EnvWorkingDir, EnvSrc;
54
55       while (auto Env = Envs->getNext()) {
56         std::string Var = Env->getName();
57         if (Var == "cwd") {
58           EnvWorkingDir = Env->getValue();
59           continue;
60         }
61         if (Var == "src") {
62           EnvSrc = Env->getValue();
63           if (sys::path::is_absolute(EnvSrc))
64             return EnvSrc;
65           RecordedResult = EnvSrc;
66           continue;
67         }
68       }
69       if (!EnvWorkingDir.empty() && !EnvSrc.empty()) {
70         auto Len = EnvWorkingDir.length();
71         if (EnvWorkingDir[Len - 1] != '/' && EnvWorkingDir[Len - 1] != '\\') {
72           std::string Path = EnvWorkingDir + "\\" + EnvSrc;
73           std::replace(Path.begin(), Path.end(), '/', '\\');
74           // We will return it as full path if we can't find a better one.
75           if (sys::path::is_absolute(Path))
76             SourceFileFullPath = Path;
77         }
78       }
79     }
80   }
81
82   if (!RecordedResult.empty()) {
83     if (sys::path::is_absolute(RecordedResult))
84       return RecordedResult;
85
86     // This searches name that has same basename as the one in RecordedResult.
87     auto OneSrcFile = Session.findOneSourceFile(
88         this, RecordedResult, PDB_NameSearchFlags::NS_CaseInsensitive);
89     if (OneSrcFile)
90       return OneSrcFile->getFileName();
91   }
92
93   // At this point, we have to walk through all source files of this compiland,
94   // and determine the right source file if any that is used to generate this
95   // compiland based on language indicated in compilanddetails language field.
96   auto Details = findOneChild<PDBSymbolCompilandDetails>();
97   PDB_Lang Lang = Details ? Details->getLanguage() : PDB_Lang::Cpp;
98   auto SrcFiles = Session.getSourceFilesForCompiland(*this);
99   if (SrcFiles) {
100     bool LangC = (Lang == PDB_Lang::Cpp || Lang == PDB_Lang::C);
101     while (auto File = SrcFiles->getNext()) {
102       std::string FileName = File->getFileName();
103       auto file_extension = sys::path::extension(FileName);
104       if (StringSwitch<bool>(file_extension.lower())
105               .Case(".cpp", LangC)
106               .Case(".c", LangC)
107               .Case(".cc", LangC)
108               .Case(".cxx", LangC)
109               .Case(".asm", Lang == PDB_Lang::Masm)
110               .Default(false))
111         return File->getFileName();
112     }
113   }
114
115   return SourceFileFullPath;
116 }