1 //===------- SourceInfo.h - Target independent OpenMP target RTL -- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Methods used to describe source information in target regions
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef _SOURCE_INFO_H_
14 #define _SOURCE_INFO_H_
15 
16 #include <string>
17 
18 #ifdef _WIN32
19 constexpr bool OSWindows = true;
20 #else
21 constexpr bool OSWindows = false;
22 #endif
23 
24 /// Type alias for source location information for variable mappings with
25 /// data layout ";name;filename;row;col;;\0" from clang.
26 using map_var_info_t = void *;
27 
28 /// The ident structure that describes a source location from kmp.h. with
29 /// source location string data as ";filename;function;line;column;;\0".
30 struct ident_t {
31   // Ident_t flags described in kmp.h.
32   int32_t reserved_1;
33   int32_t flags;
34   int32_t reserved_2;
35   int32_t reserved_3;
36   char const *psource;
37 };
38 
39 /// Struct to hold source individual location information.
40 class SourceInfo {
41   /// Underlying string copy of the original source information.
42   const std::string SourceStr;
43 
44   /// Location fields extracted from the source information string.
45   const std::string Name;
46   const std::string Filename;
47   const int32_t Line;
48   const int32_t Column;
49 
initStr(const void * Name)50   std::string initStr(const void *Name) {
51     if (!Name)
52       return ";unknown;unknown;0;0;;";
53 
54     std::string Str = std::string(reinterpret_cast<const char *>(Name));
55     if (Str.find(';') == std::string::npos)
56       return ";" + Str + ";unknown;0;0;;";
57     return Str;
58   }
59 
initStr(const ident_t * Loc)60   std::string initStr(const ident_t *Loc) {
61     if (!Loc)
62       return ";unknown;unknown;0;0;;";
63     return std::string(reinterpret_cast<const char *>(Loc->psource));
64   }
65 
66   /// Get n-th substring in an expression separated by ;.
getSubstring(const unsigned N)67   std::string getSubstring(const unsigned N) const {
68     std::size_t Begin = SourceStr.find(';');
69     std::size_t End = SourceStr.find(';', Begin + 1);
70     for (unsigned I = 0; I < N; I++) {
71       Begin = End;
72       End = SourceStr.find(';', Begin + 1);
73     }
74     return SourceStr.substr(Begin + 1, End - Begin - 1);
75   };
76 
77   /// Get the filename from a full path.
removePath(const std::string & Path)78   std::string removePath(const std::string &Path) const {
79     std::size_t Pos = (OSWindows) ? Path.rfind('\\') : Path.rfind('/');
80     return Path.substr(Pos + 1);
81   };
82 
83 public:
SourceInfo(const ident_t * Loc)84   SourceInfo(const ident_t *Loc)
85       : SourceStr(initStr(Loc)), Name(getSubstring(1)),
86         Filename(removePath(getSubstring(0))), Line(std::stoi(getSubstring(2))),
87         Column(std::stoi(getSubstring(3))) {}
88 
SourceInfo(const map_var_info_t Name)89   SourceInfo(const map_var_info_t Name)
90       : SourceStr(initStr(Name)), Name(getSubstring(0)),
91         Filename(removePath(getSubstring(1))), Line(std::stoi(getSubstring(2))),
92         Column(std::stoi(getSubstring(3))) {}
93 
getName()94   const char *getName() const { return Name.c_str(); }
getFilename()95   const char *getFilename() const { return Filename.c_str(); }
getProfileLocation()96   const char *getProfileLocation() const { return SourceStr.data(); }
getLine()97   int32_t getLine() const { return Line; }
getColumn()98   int32_t getColumn() const { return Column; }
isAvailible()99   bool isAvailible() const { return (Line || Column); }
100 };
101 
102 /// Standalone function for getting the variable name of a mapping.
getNameFromMapping(const map_var_info_t Name)103 static inline std::string getNameFromMapping(const map_var_info_t Name) {
104   if (!Name)
105     return "unknown";
106 
107   const std::string NameStr(reinterpret_cast<const char *>(Name));
108   std::size_t Begin = NameStr.find(';');
109   std::size_t End = NameStr.find(';', Begin + 1);
110   return NameStr.substr(Begin + 1, End - Begin - 1);
111 }
112 
113 #endif
114