• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //
3 // Copyright 2017 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18 
19 #ifndef GRPC_SRC_CORE_UTIL_DEBUG_LOCATION_H
20 #define GRPC_SRC_CORE_UTIL_DEBUG_LOCATION_H
21 
22 #include <grpc/support/port_platform.h>
23 
24 #include <utility>
25 
26 #include "absl/strings/str_cat.h"
27 
28 #if defined(__has_builtin)
29 #if __has_builtin(__builtin_FILE)
30 #define GRPC_DEFAULT_FILE __builtin_FILE()
31 #endif
32 #endif
33 #ifndef GRPC_DEFAULT_FILE
34 #define GRPC_DEFAULT_FILE "<unknown>"
35 #endif
36 #if defined(__has_builtin)
37 #if __has_builtin(__builtin_LINE)
38 #define GRPC_DEFAULT_LINE __builtin_LINE()
39 #endif
40 #endif
41 #ifndef GRPC_DEFAULT_LINE
42 #define GRPC_DEFAULT_LINE -1
43 #endif
44 
45 namespace grpc_core {
46 
47 class SourceLocation {
48  public:
49   // NOLINTNEXTLINE
50   SourceLocation(const char* file = GRPC_DEFAULT_FILE,
51                  int line = GRPC_DEFAULT_LINE)
file_(file)52       : file_(file), line_(line) {}
file()53   const char* file() const { return file_; }
line()54   int line() const { return line_; }
55 
56  private:
57   const char* file_;
58   int line_;
59 };
60 
61 template <typename Sink>
AbslStringify(Sink & out,const SourceLocation & location)62 void AbslStringify(Sink& out, const SourceLocation& location) {
63   out.Append(absl::StrCat("[", location.file(), ":", location.line(), "]"));
64 }
65 
66 // Used for tracking file and line where a call is made for debug builds.
67 // No-op for non-debug builds.
68 // Callers can use the DEBUG_LOCATION macro in either case.
69 #ifndef NDEBUG
70 class DebugLocation {
71  public:
72   DebugLocation(const char* file = GRPC_DEFAULT_FILE,
73                 int line = GRPC_DEFAULT_LINE)
location_(file,line)74       : location_(file, line) {}
DebugLocation(SourceLocation location)75   explicit DebugLocation(SourceLocation location) : location_(location) {}
file()76   const char* file() const { return location_.file(); }
line()77   int line() const { return location_.line(); }
78 
79  private:
80   SourceLocation location_;
81 };
82 #else
83 class DebugLocation {
84  public:
DebugLocation()85   DebugLocation() {}
DebugLocation(SourceLocation)86   explicit DebugLocation(SourceLocation) {}
DebugLocation(const char *,int)87   DebugLocation(const char* /* file */, int /* line */) {}
file()88   const char* file() const { return nullptr; }
line()89   int line() const { return -1; }
90 };
91 #endif
92 
93 template <typename T>
94 struct ValueWithDebugLocation {
95   // NOLINTNEXTLINE
96   ValueWithDebugLocation(T&& value, DebugLocation debug_location = {})
valueValueWithDebugLocation97       : value(std::forward<T>(value)), debug_location(debug_location) {}
98   T value;
99   GPR_NO_UNIQUE_ADDRESS DebugLocation debug_location;
100 };
101 
102 #define DEBUG_LOCATION ::grpc_core::DebugLocation(__FILE__, __LINE__)
103 
104 }  // namespace grpc_core
105 
106 #endif  // GRPC_SRC_CORE_UTIL_DEBUG_LOCATION_H
107