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