1 //===- NodeIntrospection.h ------------------------------------*- C++ -*---===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains the implementation of the NodeIntrospection. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CLANG_TOOLING_NODEINTROSPECTION_H 14 #define LLVM_CLANG_TOOLING_NODEINTROSPECTION_H 15 16 #include "clang/AST/ASTTypeTraits.h" 17 #include "clang/AST/DeclarationName.h" 18 #include "llvm/ADT/IntrusiveRefCntPtr.h" 19 #include <set> 20 21 namespace clang { 22 23 class Stmt; 24 class Decl; 25 class CXXCtorInitializer; 26 class NestedNameSpecifierLoc; 27 class TemplateArgumentLoc; 28 class CXXBaseSpecifier; 29 struct DeclarationNameInfo; 30 31 namespace tooling { 32 33 class LocationCall; 34 using SharedLocationCall = llvm::IntrusiveRefCntPtr<LocationCall>; 35 36 class LocationCall : public llvm::ThreadSafeRefCountedBase<LocationCall> { 37 public: 38 enum LocationCallFlags { NoFlags, ReturnsPointer, IsCast }; 39 LocationCall(SharedLocationCall on, std::string name, 40 LocationCallFlags flags = NoFlags) m_flags(flags)41 : m_flags(flags), m_on(std::move(on)), m_name(std::move(name)) {} 42 on()43 LocationCall *on() const { return m_on.get(); } name()44 StringRef name() const { return m_name; } returnsPointer()45 bool returnsPointer() const { return m_flags & ReturnsPointer; } isCast()46 bool isCast() const { return m_flags & IsCast; } 47 48 private: 49 LocationCallFlags m_flags; 50 SharedLocationCall m_on; 51 std::string m_name; 52 }; 53 54 class LocationCallFormatterCpp { 55 public: 56 static void print(const LocationCall &Call, llvm::raw_ostream &OS); 57 static std::string format(const LocationCall &Call); 58 }; 59 60 namespace internal { 61 struct RangeLessThan { 62 bool operator()(std::pair<SourceRange, SharedLocationCall> const &LHS, 63 std::pair<SourceRange, SharedLocationCall> const &RHS) const; 64 bool 65 operator()(std::pair<SourceLocation, SharedLocationCall> const &LHS, 66 std::pair<SourceLocation, SharedLocationCall> const &RHS) const; 67 }; 68 69 } // namespace internal 70 71 // Note that this container stores unique results in a deterministic, but 72 // the location calls are in an unspecified order. Clients which desire 73 // a particular order for the location calls, such as alphabetical, 74 // should sort results after retrieval, because the order is dependent 75 // on how the LocationCalls are formatted. 76 template <typename T, typename U> 77 using UniqueMultiMap = std::set<std::pair<T, U>, internal::RangeLessThan>; 78 79 using SourceLocationMap = UniqueMultiMap<SourceLocation, SharedLocationCall>; 80 using SourceRangeMap = UniqueMultiMap<SourceRange, SharedLocationCall>; 81 82 struct NodeLocationAccessors { 83 SourceLocationMap LocationAccessors; 84 SourceRangeMap RangeAccessors; 85 }; 86 87 namespace NodeIntrospection { 88 bool hasIntrospectionSupport(); 89 NodeLocationAccessors GetLocations(clang::Stmt const *Object); 90 NodeLocationAccessors GetLocations(clang::Decl const *Object); 91 NodeLocationAccessors GetLocations(clang::CXXCtorInitializer const *Object); 92 NodeLocationAccessors GetLocations(clang::NestedNameSpecifierLoc const &); 93 NodeLocationAccessors GetLocations(clang::TemplateArgumentLoc const &); 94 NodeLocationAccessors GetLocations(clang::CXXBaseSpecifier const *); 95 NodeLocationAccessors GetLocations(clang::TypeLoc const &); 96 NodeLocationAccessors GetLocations(clang::DeclarationNameInfo const &); 97 NodeLocationAccessors GetLocations(clang::DynTypedNode const &Node); 98 } // namespace NodeIntrospection 99 } // namespace tooling 100 } // namespace clang 101 #endif 102