blob: 43db7d9de9420457f82d73be50b68f65370c7fdd [file] [log] [blame]
// 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_PLUGINS_UTIL_H_
#define TOOLS_CLANG_PLUGINS_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"
// 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();
}
namespace chrome_checker {
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 chrome_checker
#endif // TOOLS_CLANG_PLUGINS_UTIL_H_