1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BASE_LOCATION_H_
6 #define BASE_LOCATION_H_
7 
8 #include <stddef.h>
9 
10 #include <cassert>
11 #include <string>
12 
13 #include "base/base_export.h"
14 #include "base/debug/debugging_buildflags.h"
15 #include "base/hash.h"
16 
17 namespace base {
18 
19 // Location provides basic info where of an object was constructed, or was
20 // significantly brought to life.
21 class BASE_EXPORT Location {
22  public:
23   Location();
24   Location(const Location& other);
25 
26   // Only initializes the file name and program counter, the source information
27   // will be null for the strings, and -1 for the line number.
28   // TODO(http://crbug.com/760702) remove file name from this constructor.
29   Location(const char* file_name, const void* program_counter);
30 
31   // Constructor should be called with a long-lived char*, such as __FILE__.
32   // It assumes the provided value will persist as a global constant, and it
33   // will not make a copy of it.
34   Location(const char* function_name,
35            const char* file_name,
36            int line_number,
37            const void* program_counter);
38 
39   // Comparator for hash map insertion. The program counter should uniquely
40   // identify a location.
41   bool operator==(const Location& other) const {
42     return program_counter_ == other.program_counter_;
43   }
44 
45   // Returns true if there is source code location info. If this is false,
46   // the Location object only contains a program counter or is
47   // default-initialized (the program counter is also null).
has_source_info()48   bool has_source_info() const { return function_name_ && file_name_; }
49 
50   // Will be nullptr for default initialized Location objects and when source
51   // names are disabled.
function_name()52   const char* function_name() const { return function_name_; }
53 
54   // Will be nullptr for default initialized Location objects and when source
55   // names are disabled.
file_name()56   const char* file_name() const { return file_name_; }
57 
58   // Will be -1 for default initialized Location objects and when source names
59   // are disabled.
line_number()60   int line_number() const { return line_number_; }
61 
62   // The address of the code generating this Location object. Should always be
63   // valid except for default initialized Location objects, which will be
64   // nullptr.
program_counter()65   const void* program_counter() const { return program_counter_; }
66 
67   // Converts to the most user-readable form possible. If function and filename
68   // are not available, this will return "pc:<hex address>".
69   std::string ToString() const;
70 
71   static Location CreateFromHere(const char* file_name);
72   static Location CreateFromHere(const char* function_name,
73                                  const char* file_name,
74                                  int line_number);
75 
76  private:
77   const char* function_name_ = nullptr;
78   const char* file_name_ = nullptr;
79   int line_number_ = -1;
80   const void* program_counter_ = nullptr;
81 };
82 
83 BASE_EXPORT const void* GetProgramCounter();
84 
85 // The macros defined here will expand to the current function.
86 #if BUILDFLAG(ENABLE_LOCATION_SOURCE)
87 
88 // Full source information should be included.
89 #define FROM_HERE FROM_HERE_WITH_EXPLICIT_FUNCTION(__func__)
90 #define FROM_HERE_WITH_EXPLICIT_FUNCTION(function_name) \
91   ::base::Location::CreateFromHere(function_name, __FILE__, __LINE__)
92 
93 #else
94 
95 // TODO(http://crbug.com/760702) remove the __FILE__ argument from these calls.
96 #define FROM_HERE ::base::Location::CreateFromHere(__FILE__)
97 #define FROM_HERE_WITH_EXPLICIT_FUNCTION(function_name) \
98   ::base::Location::CreateFromHere(function_name, __FILE__, -1)
99 
100 #endif
101 
102 }  // namespace base
103 
104 namespace std {
105 
106 // Specialization for using Location in hash tables.
107 template <>
108 struct hash<::base::Location> {
109   std::size_t operator()(const ::base::Location& loc) const {
110     const void* program_counter = loc.program_counter();
111     return base::Hash(&program_counter, sizeof(void*));
112   }
113 };
114 
115 }  // namespace std
116 
117 #endif  // BASE_LOCATION_H_
118