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_
|