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)
41       : m_flags(flags), m_on(std::move(on)), m_name(std::move(name)) {}
42 
43   LocationCall *on() const { return m_on.get(); }
44   StringRef name() const { return m_name; }
45   bool returnsPointer() const { return m_flags & ReturnsPointer; }
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