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.
5 #ifndef BASE_LOCATION_H_
6 #define BASE_LOCATION_H_
14 #include "base/base_export.h"
15 #include "base/debug/debugging_buildflags.h"
16 #include "base/hash/hash.h"
17 #include "build/build_config.h"
21 #if defined(__has_builtin)
22 // Clang allows detection of these builtins.
23 #define SUPPORTS_LOCATION_BUILTINS \
24 (__has_builtin(__builtin_FUNCTION) && __has_builtin(__builtin_FILE) && \
25 __has_builtin(__builtin_LINE))
26 #elif defined(COMPILER_GCC) && __GNUC__ >= 7
27 // GCC has supported these for a long time, but they point at the function
28 // declaration in the case of default arguments, rather than at the call site.
29 #define SUPPORTS_LOCATION_BUILTINS 1
31 #define SUPPORTS_LOCATION_BUILTINS 0
34 // Location provides basic info where of an object was constructed, or was
35 // significantly brought to life.
36 class BASE_EXPORT Location {
39 Location(const Location& other);
41 // Only initializes the file name and program counter, the source information
42 // will be null for the strings, and -1 for the line number.
43 // TODO(http://crbug.com/760702) remove file name from this constructor.
44 Location(const char* file_name, const void* program_counter);
46 // Constructor should be called with a long-lived char*, such as __FILE__.
47 // It assumes the provided value will persist as a global constant, and it
48 // will not make a copy of it.
49 Location(const char* function_name,
50 const char* file_name,
52 const void* program_counter);
54 // Comparator for hash map insertion. The program counter should uniquely
55 // identify a location.
56 bool operator==(const Location& other) const {
57 return program_counter_ == other.program_counter_;
60 // Returns true if there is source code location info. If this is false,
61 // the Location object only contains a program counter or is
62 // default-initialized (the program counter is also null).
63 bool has_source_info() const { return function_name_ && file_name_; }
65 // Will be nullptr for default initialized Location objects and when source
66 // names are disabled.
67 const char* function_name() const { return function_name_; }
69 // Will be nullptr for default initialized Location objects and when source
70 // names are disabled.
71 const char* file_name() const { return file_name_; }
73 // Will be -1 for default initialized Location objects and when source names
75 int line_number() const { return line_number_; }
77 // The address of the code generating this Location object. Should always be
78 // valid except for default initialized Location objects, which will be
80 const void* program_counter() const { return program_counter_; }
82 // Converts to the most user-readable form possible. If function and filename
83 // are not available, this will return "pc:<hex address>".
84 std::string ToString() const;
86 #if !BUILDFLAG(FROM_HERE_USES_LOCATION_BUILTINS)
87 #if !BUILDFLAG(ENABLE_LOCATION_SOURCE)
88 static Location CreateFromHere(const char* file_name);
90 static Location CreateFromHere(const char* function_name,
91 const char* file_name,
96 #if SUPPORTS_LOCATION_BUILTINS && BUILDFLAG(ENABLE_LOCATION_SOURCE)
97 static Location Current(const char* function_name = __builtin_FUNCTION(),
98 const char* file_name = __builtin_FILE(),
99 int line_number = __builtin_LINE());
100 #elif SUPPORTS_LOCATION_BUILTINS
101 static Location Current(const char* file_name = __builtin_FILE());
103 static Location Current();
107 const char* function_name_ = nullptr;
108 const char* file_name_ = nullptr;
109 int line_number_ = -1;
110 const void* program_counter_ = nullptr;
113 BASE_EXPORT const void* GetProgramCounter();
115 #if BUILDFLAG(FROM_HERE_USES_LOCATION_BUILTINS)
117 #define FROM_HERE ::base::Location::Current()
119 // The macros defined here will expand to the current function.
120 #elif BUILDFLAG(ENABLE_LOCATION_SOURCE)
122 // Full source information should be included.
123 #define FROM_HERE ::base::Location::CreateFromHere(__func__, __FILE__, __LINE__)
127 // TODO(http://crbug.com/760702) remove the __FILE__ argument from these calls.
128 #define FROM_HERE ::base::Location::CreateFromHere(__FILE__)
136 // Specialization for using Location in hash tables.
138 struct hash<::base::Location> {
139 std::size_t operator()(const ::base::Location& loc) const {
140 const void* program_counter = loc.program_counter();
141 return base::FastHash(base::as_bytes(base::make_span(&program_counter, 1)));
147 #endif // BASE_LOCATION_H_