Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===- ExtractAPI/DeclarationFragments.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
/// \file
10
/// This file defines the Declaration Fragments related classes.
11
///
12
/// Declaration Fragments represent parts of a symbol declaration tagged with
13
/// syntactic/semantic information.
14
/// See https://github.com/apple/swift-docc-symbolkit
15
///
16
//===----------------------------------------------------------------------===//
17
 
18
#ifndef LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
19
#define LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
20
 
21
#include "clang/AST/ASTContext.h"
22
#include "clang/AST/Decl.h"
23
#include "clang/AST/DeclCXX.h"
24
#include "clang/AST/DeclObjC.h"
25
#include "clang/Lex/MacroInfo.h"
26
#include "llvm/ADT/StringRef.h"
27
#include <vector>
28
 
29
namespace clang {
30
namespace extractapi {
31
 
32
/// DeclarationFragments is a vector of tagged important parts of a symbol's
33
/// declaration.
34
///
35
/// The fragments sequence can be joined to form spans of declaration text, with
36
/// attached information useful for purposes like syntax-highlighting etc.
37
/// For example:
38
/// \code
39
///   const -> keyword    "const"
40
///   int   -> type       "int"
41
///   pi;   -> identifier "pi"
42
/// \endcode
43
class DeclarationFragments {
44
public:
45
  DeclarationFragments() = default;
46
 
47
  /// The kind of a fragment.
48
  enum class FragmentKind {
49
    /// Unknown fragment kind.
50
    None,
51
 
52
    Keyword,
53
    Attribute,
54
    NumberLiteral,
55
    StringLiteral,
56
    Identifier,
57
 
58
    /// Identifier that refers to a type in the context.
59
    TypeIdentifier,
60
 
61
    /// Parameter that's used as generics in the context. For example template
62
    /// parameters.
63
    GenericParameter,
64
 
65
    /// External parameters in Objective-C methods.
66
    /// For example, \c forKey in
67
    /// \code{.m}
68
    ///   - (void) setValue:(Value)value forKey(Key)key
69
    /// \endcode
70
    ExternalParam,
71
 
72
    /// Internal/local parameters in Objective-C methods.
73
    /// For example, \c key in
74
    /// \code{.m}
75
    ///   - (void) setValue:(Value)value forKey(Key)key
76
    /// \endcode
77
    InternalParam,
78
 
79
    Text,
80
  };
81
 
82
  /// Fragment holds information of a single fragment.
83
  struct Fragment {
84
    std::string Spelling;
85
    FragmentKind Kind;
86
 
87
    /// The USR of the fragment symbol, if applicable.
88
    std::string PreciseIdentifier;
89
 
90
    /// The associated declaration, if applicable. This is not intended to be
91
    /// used outside of libclang.
92
    const Decl *Declaration;
93
 
94
    Fragment(StringRef Spelling, FragmentKind Kind, StringRef PreciseIdentifier,
95
             const Decl *Declaration)
96
        : Spelling(Spelling), Kind(Kind), PreciseIdentifier(PreciseIdentifier),
97
          Declaration(Declaration) {}
98
  };
99
 
100
  const std::vector<Fragment> &getFragments() const { return Fragments; }
101
 
102
  /// Append a new Fragment to the end of the Fragments.
103
  ///
104
  /// \returns a reference to the DeclarationFragments object itself after
105
  /// appending to chain up consecutive appends.
106
  DeclarationFragments &append(StringRef Spelling, FragmentKind Kind,
107
                               StringRef PreciseIdentifier = "",
108
                               const Decl *Declaration = nullptr) {
109
    if (Kind == FragmentKind::Text && !Fragments.empty() &&
110
        Fragments.back().Kind == FragmentKind::Text) {
111
      // If appending a text fragment, and the last fragment is also text,
112
      // merge into the last fragment.
113
      Fragments.back().Spelling.append(Spelling.data(), Spelling.size());
114
    } else {
115
      Fragments.emplace_back(Spelling, Kind, PreciseIdentifier, Declaration);
116
    }
117
    return *this;
118
  }
119
 
120
  /// Append another DeclarationFragments to the end.
121
  ///
122
  /// Note: \p Other is moved from and cannot be used after a call to this
123
  /// method.
124
  ///
125
  /// \returns a reference to the DeclarationFragments object itself after
126
  /// appending to chain up consecutive appends.
127
  DeclarationFragments &append(DeclarationFragments &&Other) {
128
    Fragments.insert(Fragments.end(),
129
                     std::make_move_iterator(Other.Fragments.begin()),
130
                     std::make_move_iterator(Other.Fragments.end()));
131
    Other.Fragments.clear();
132
    return *this;
133
  }
134
 
135
  /// Append a text Fragment of a space character.
136
  ///
137
  /// \returns a reference to the DeclarationFragments object itself after
138
  /// appending to chain up consecutive appends.
139
  DeclarationFragments &appendSpace();
140
 
141
  /// Get the string description of a FragmentKind \p Kind.
142
  static StringRef getFragmentKindString(FragmentKind Kind);
143
 
144
  /// Get the corresponding FragmentKind from string \p S.
145
  static FragmentKind parseFragmentKindFromString(StringRef S);
146
 
147
private:
148
  std::vector<Fragment> Fragments;
149
};
150
 
151
/// Store function signature information with DeclarationFragments of the
152
/// return type and parameters.
153
class FunctionSignature {
154
public:
155
  FunctionSignature() = default;
156
 
157
  /// Parameter holds the name and DeclarationFragments of a single parameter.
158
  struct Parameter {
159
    std::string Name;
160
    DeclarationFragments Fragments;
161
 
162
    Parameter(StringRef Name, DeclarationFragments Fragments)
163
        : Name(Name), Fragments(Fragments) {}
164
  };
165
 
166
  const std::vector<Parameter> &getParameters() const { return Parameters; }
167
  const DeclarationFragments &getReturnType() const { return ReturnType; }
168
 
169
  FunctionSignature &addParameter(StringRef Name,
170
                                  DeclarationFragments Fragments) {
171
    Parameters.emplace_back(Name, Fragments);
172
    return *this;
173
  }
174
 
175
  void setReturnType(DeclarationFragments RT) { ReturnType = RT; }
176
 
177
  /// Determine if the FunctionSignature is empty.
178
  ///
179
  /// \returns true if the return type DeclarationFragments is empty and there
180
  /// is no parameter, otherwise false.
181
  bool empty() const {
182
    return Parameters.empty() && ReturnType.getFragments().empty();
183
  }
184
 
185
private:
186
  std::vector<Parameter> Parameters;
187
  DeclarationFragments ReturnType;
188
};
189
 
190
/// A factory class to build DeclarationFragments for different kinds of Decl.
191
class DeclarationFragmentsBuilder {
192
public:
193
  /// Build DeclarationFragments for a variable declaration VarDecl.
194
  static DeclarationFragments getFragmentsForVar(const VarDecl *);
195
 
196
  /// Build DeclarationFragments for a function declaration FunctionDecl.
197
  static DeclarationFragments getFragmentsForFunction(const FunctionDecl *);
198
 
199
  /// Build DeclarationFragments for an enum constant declaration
200
  /// EnumConstantDecl.
201
  static DeclarationFragments
202
  getFragmentsForEnumConstant(const EnumConstantDecl *);
203
 
204
  /// Build DeclarationFragments for an enum declaration EnumDecl.
205
  static DeclarationFragments getFragmentsForEnum(const EnumDecl *);
206
 
207
  /// Build DeclarationFragments for a field declaration FieldDecl.
208
  static DeclarationFragments getFragmentsForField(const FieldDecl *);
209
 
210
  /// Build DeclarationFragments for a struct record declaration RecordDecl.
211
  static DeclarationFragments getFragmentsForStruct(const RecordDecl *);
212
 
213
  /// Build DeclarationFragments for an Objective-C category declaration
214
  /// ObjCCategoryDecl.
215
  static DeclarationFragments
216
  getFragmentsForObjCCategory(const ObjCCategoryDecl *);
217
 
218
  /// Build DeclarationFragments for an Objective-C interface declaration
219
  /// ObjCInterfaceDecl.
220
  static DeclarationFragments
221
  getFragmentsForObjCInterface(const ObjCInterfaceDecl *);
222
 
223
  /// Build DeclarationFragments for an Objective-C method declaration
224
  /// ObjCMethodDecl.
225
  static DeclarationFragments getFragmentsForObjCMethod(const ObjCMethodDecl *);
226
 
227
  /// Build DeclarationFragments for an Objective-C property declaration
228
  /// ObjCPropertyDecl.
229
  static DeclarationFragments
230
  getFragmentsForObjCProperty(const ObjCPropertyDecl *);
231
 
232
  /// Build DeclarationFragments for an Objective-C protocol declaration
233
  /// ObjCProtocolDecl.
234
  static DeclarationFragments
235
  getFragmentsForObjCProtocol(const ObjCProtocolDecl *);
236
 
237
  /// Build DeclarationFragments for a macro.
238
  ///
239
  /// \param Name name of the macro.
240
  /// \param MD the associated MacroDirective.
241
  static DeclarationFragments getFragmentsForMacro(StringRef Name,
242
                                                   const MacroDirective *MD);
243
 
244
  /// Build DeclarationFragments for a typedef \p TypedefNameDecl.
245
  static DeclarationFragments
246
  getFragmentsForTypedef(const TypedefNameDecl *Decl);
247
 
248
  /// Build sub-heading fragments for a NamedDecl.
249
  static DeclarationFragments getSubHeading(const NamedDecl *);
250
 
251
  /// Build sub-heading fragments for an Objective-C method.
252
  static DeclarationFragments getSubHeading(const ObjCMethodDecl *);
253
 
254
  /// Build a sub-heading for macro \p Name.
255
  static DeclarationFragments getSubHeadingForMacro(StringRef Name);
256
 
257
  /// Build FunctionSignature for a function-like declaration \c FunctionT like
258
  /// FunctionDecl or ObjCMethodDecl.
259
  ///
260
  /// The logic and implementation of building a signature for a FunctionDecl
261
  /// and an ObjCMethodDecl are exactly the same, but they do not share a common
262
  /// base. This template helps reuse the code.
263
  template <typename FunctionT>
264
  static FunctionSignature getFunctionSignature(const FunctionT *);
265
 
266
private:
267
  DeclarationFragmentsBuilder() = delete;
268
 
269
  /// Build DeclarationFragments for a QualType.
270
  static DeclarationFragments getFragmentsForType(const QualType, ASTContext &,
271
                                                  DeclarationFragments &);
272
 
273
  /// Build DeclarationFragments for a Type.
274
  static DeclarationFragments getFragmentsForType(const Type *, ASTContext &,
275
                                                  DeclarationFragments &);
276
 
277
  /// Build DeclarationFragments for a NestedNameSpecifier.
278
  static DeclarationFragments getFragmentsForNNS(const NestedNameSpecifier *,
279
                                                 ASTContext &,
280
                                                 DeclarationFragments &);
281
 
282
  /// Build DeclarationFragments for Qualifiers.
283
  static DeclarationFragments getFragmentsForQualifiers(const Qualifiers quals);
284
 
285
  /// Build DeclarationFragments for a parameter variable declaration
286
  /// ParmVarDecl.
287
  static DeclarationFragments getFragmentsForParam(const ParmVarDecl *);
288
};
289
 
290
} // namespace extractapi
291
} // namespace clang
292
 
293
#endif // LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H