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 static const bool OS_WINDOWS = true;
20 #else
21 static const bool OS_WINDOWS = 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     else
54       return std::string(reinterpret_cast<const char *>(name));
55   }
56 
57   /// Get n-th substring in an expression separated by ;.
getSubstring(const int n)58   std::string getSubstring(const int n) const {
59     std::size_t begin = sourceStr.find(';');
60     std::size_t end = sourceStr.find(';', begin + 1);
61     for (int i = 0; i < n; i++) {
62       begin = end;
63       end = sourceStr.find(';', begin + 1);
64     }
65     return sourceStr.substr(begin + 1, end - begin - 1);
66   };
67 
68   /// Get the filename from a full path.
removePath(const std::string & path)69   std::string removePath(const std::string &path) const {
70     std::size_t pos = (OS_WINDOWS) ? path.rfind('\\') : path.rfind('/');
71     return path.substr(pos + 1);
72   };
73 
74 public:
SourceInfo(const ident_t * loc)75   SourceInfo(const ident_t *loc)
76       : sourceStr(initStr(loc->psource)), name(getSubstring(1)),
77         filename(removePath(getSubstring(0))), line(std::stoi(getSubstring(2))),
78         column(std::stoi(getSubstring(3))) {}
79 
SourceInfo(const map_var_info_t name)80   SourceInfo(const map_var_info_t name)
81       : sourceStr(initStr(name)), name(getSubstring(0)),
82         filename(removePath(getSubstring(1))), line(std::stoi(getSubstring(2))),
83         column(std::stoi(getSubstring(3))) {}
84 
getName()85   const char *getName() const { return name.c_str(); }
getFilename()86   const char *getFilename() const { return filename.c_str(); }
getLine()87   int32_t getLine() const { return line; }
getColumn()88   int32_t getColumn() const { return column; }
isAvailible()89   bool isAvailible() const { return (line || column); }
90 };
91 
92 /// Standalone function for getting the variable name of a mapping.
getNameFromMapping(const map_var_info_t name)93 static inline std::string getNameFromMapping(const map_var_info_t name) {
94   if (!name)
95     return "unknown";
96 
97   const std::string name_str(reinterpret_cast<const char *>(name));
98   std::size_t begin = name_str.find(';');
99   std::size_t end = name_str.find(';', begin + 1);
100   return name_str.substr(begin + 1, end - begin - 1);
101 }
102 
103 #endif
104