File: Util.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (150 lines) | stat: -rw-r--r-- 5,372 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef TOOLS_CLANG_RAW_PTR_PLUGIN_UTIL_H_
#define TOOLS_CLANG_RAW_PTR_PLUGIN_UTIL_H_

#include <string>
#include <type_traits>

#include "clang/AST/DeclBase.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/HeaderSearchOptions.h"

namespace raw_ptr_plugin {

// Utility method for subclasses to determine the namespace of the
// specified record, if any. Unnamed namespaces will be identified as
// "<anonymous namespace>".
std::string GetNamespace(const clang::Decl* record);

enum class FilenamesFollowPresumed {
  kYes,
  kNo,
};

enum class FilenameLocationType {
  // Use the location as is.
  kExactLoc,
  // Use the spelling location of the current location. This leaves a macro if
  // the token at the location came from a macro parameter.
  kSpellingLoc,
  // Use the expansion location of the current location. This always leaves a
  // macro.
  kExpansionLoc,
};

// Attempts to determine the filename for the given SourceLocation. Returns an
// empty string if the filename could not be determined.
//
// Most callers use FilenameLocationType::kSpellingLoc which gets the filename
// where a macro is used, if the name at the location is coming from a macro
// parameter. This would be used when a warning is being generated based on the
// macro inputs, rather than the macro's structure itself. It may be an
// incorrect approximation of kExpansionLoc, though.
std::string GetFilename(
    const clang::SourceManager& instance,
    clang::SourceLocation location,
    FilenameLocationType type,
    FilenamesFollowPresumed follow_presumed = FilenamesFollowPresumed::kYes);

// Utility method to obtain a "representative" source location polymorphically.
// We sometimes use a source location to determine a code owner has legitimate
// justification not to fix the issue found out by the plugin (e.g. the issue
// being inside system headers). Among several options to obtain a location,
// this utility aims to provide the best location which represents the node's
// essential token.
inline clang::SourceLocation getRepresentativeLocation(
    const clang::Stmt& node) {
  // clang::Stmt has T::getBeginLoc() and T::getEndLoc().
  // Usually the former one does better represent the location.
  //
  // e.g. clang::IfStmt
  // if (foo) {} else {}
  // ^                 ^
  // |                 getEndLoc()
  // getBeginLoc()
  //
  // e.g. clang::CastExpr
  // int x = static_cast<int>(123ll);
  //         ^                     ^
  //         |                     getEndLoc()
  //         getBeginLoc()
  return node.getBeginLoc();
}
inline clang::SourceLocation getRepresentativeLocation(
    const clang::TypeLoc& node) {
  // clang::TypeLoc has T::getBeginLoc() and T::getEndLoc().
  // As the former may refer to modifiers, we use the latter one.
  return node.getEndLoc();
}
inline clang::SourceLocation getRepresentativeLocation(
    const clang::Decl& node) {
  // Unlike other nodes, clang::Decl provides T::getLocation().
  // Usually, this provides more "representative" location.
  //
  // e.g. clang::FieldDecl
  //   int* field = nullptr;
  //   ^    ^       ^
  //   |    |       getEndLoc()
  //   |    getLocation()
  //   getBeginLoc()
  return node.getLocation();
}

template <typename Node>
bool isNodeInThirdPartyLocation(const Node& node,
                                const clang::SourceManager& source_manager) {
  const std::string& filename =
      GetFilename(source_manager, getRepresentativeLocation(node),
                  FilenameLocationType::kSpellingLoc);

  // Blink is part of the Chromium git repo, even though it contains
  // "third_party" in its path.
  if (filename.find("/third_party/blink/") != std::string::npos) {
    return false;
  }
  // Dawn repo has started using raw_ptr.
  if (filename.find("/third_party/dawn/") != std::string::npos) {
    return false;
  }
  // Otherwise, just check if the paths contains the "third_party" substring.
  // We don't want to rewrite content of such paths even if they are in the main
  // Chromium git repository.
  return filename.find("/third_party/") != std::string::npos;
}

enum LocationClassification {
  // First-party Chromium code that is part of the main project repo.
  kFirstParty,
  // Blink is first-party but is treated differently sometimes, with different
  // style rules.
  kBlink,
  // Third-party code that is owned by the Chromium project.
  kChromiumThirdParty,
  // Third-party code that is not owned by the Chromium project, imported from
  // external projects.
  kThirdParty,
  // Generated code which is not checked in.
  kGenerated,
  // Code that is generated by a macro.
  kMacro,
  // System headers (specified to Clang by -isystem).
  kSystem,
};

// Determines if a SourceLocation is considered part of first-party or
// third-party code, or is generated code, which can be used to determine how or
// which rules should be enforced.
LocationClassification ClassifySourceLocation(
    const clang::HeaderSearchOptions& search,
    const clang::SourceManager& sm,
    clang::SourceLocation loc);

}  // namespace raw_ptr_plugin

#endif  // TOOLS_CLANG_RAW_PTR_PLUGIN_UTIL_H_