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