1 //===--- CommentSema.h - Doxygen comment semantic analysis ------*- 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 defines the semantic analysis class for Doxygen comments.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CLANG_AST_COMMENTSEMA_H
14 #define LLVM_CLANG_AST_COMMENTSEMA_H
15 
16 #include "clang/AST/Comment.h"
17 #include "clang/Basic/Diagnostic.h"
18 #include "clang/Basic/SourceLocation.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/StringMap.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/Support/Allocator.h"
23 
24 namespace clang {
25 class Decl;
26 class SourceMgr;
27 class Preprocessor;
28 
29 namespace comments {
30 class CommandTraits;
31 
32 class Sema {
33   Sema(const Sema &) = delete;
34   void operator=(const Sema &) = delete;
35 
36   /// Allocator for AST nodes.
37   llvm::BumpPtrAllocator &Allocator;
38 
39   /// Source manager for the comment being parsed.
40   const SourceManager &SourceMgr;
41 
42   DiagnosticsEngine &Diags;
43 
44   CommandTraits &Traits;
45 
46   const Preprocessor *PP;
47 
48   /// Information about the declaration this comment is attached to.
49   DeclInfo *ThisDeclInfo;
50 
51   /// Comment AST nodes that correspond to parameter names in
52   /// \c TemplateParameters.
53   ///
54   /// Contains a valid value if \c DeclInfo->IsFilled is true.
55   llvm::StringMap<TParamCommandComment *> TemplateParameterDocs;
56 
57   /// AST node for the \command and its aliases.
58   const BlockCommandComment *BriefCommand;
59 
60   /// AST node for the \\headerfile command.
61   const BlockCommandComment *HeaderfileCommand;
62 
63   DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
64     return Diags.Report(Loc, DiagID);
65   }
66 
67   /// A stack of HTML tags that are currently open (not matched with closing
68   /// tags).
69   SmallVector<HTMLStartTagComment *, 8> HTMLOpenTags;
70 
71 public:
72   Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr,
73        DiagnosticsEngine &Diags, CommandTraits &Traits,
74        const Preprocessor *PP);
75 
76   void setDecl(const Decl *D);
77 
78   /// Returns a copy of array, owned by Sema's allocator.
79   template<typename T>
80   ArrayRef<T> copyArray(ArrayRef<T> Source) {
81     if (!Source.empty())
82       return Source.copy(Allocator);
83     return std::nullopt;
84   }
85 
86   ParagraphComment *actOnParagraphComment(
87       ArrayRef<InlineContentComment *> Content);
88 
89   BlockCommandComment *actOnBlockCommandStart(SourceLocation LocBegin,
90                                               SourceLocation LocEnd,
91                                               unsigned CommandID,
92                                               CommandMarkerKind CommandMarker);
93 
94   void actOnBlockCommandArgs(BlockCommandComment *Command,
95                              ArrayRef<BlockCommandComment::Argument> Args);
96 
97   void actOnBlockCommandFinish(BlockCommandComment *Command,
98                                ParagraphComment *Paragraph);
99 
100   ParamCommandComment *actOnParamCommandStart(SourceLocation LocBegin,
101                                               SourceLocation LocEnd,
102                                               unsigned CommandID,
103                                               CommandMarkerKind CommandMarker);
104 
105   void actOnParamCommandDirectionArg(ParamCommandComment *Command,
106                                      SourceLocation ArgLocBegin,
107                                      SourceLocation ArgLocEnd,
108                                      StringRef Arg);
109 
110   void actOnParamCommandParamNameArg(ParamCommandComment *Command,
111                                      SourceLocation ArgLocBegin,
112                                      SourceLocation ArgLocEnd,
113                                      StringRef Arg);
114 
115   void actOnParamCommandFinish(ParamCommandComment *Command,
116                                ParagraphComment *Paragraph);
117 
118   TParamCommandComment *actOnTParamCommandStart(SourceLocation LocBegin,
119                                                 SourceLocation LocEnd,
120                                                 unsigned CommandID,
121                                                 CommandMarkerKind CommandMarker);
122 
123   void actOnTParamCommandParamNameArg(TParamCommandComment *Command,
124                                       SourceLocation ArgLocBegin,
125                                       SourceLocation ArgLocEnd,
126                                       StringRef Arg);
127 
128   void actOnTParamCommandFinish(TParamCommandComment *Command,
129                                 ParagraphComment *Paragraph);
130 
131   InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
132                                            SourceLocation CommandLocEnd,
133                                            unsigned CommandID,
134                                            ArrayRef<Comment::Argument> Args);
135 
136   InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
137                                             SourceLocation LocEnd,
138                                             StringRef CommandName);
139 
140   InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
141                                             SourceLocation LocEnd,
142                                             unsigned CommandID);
143 
144   TextComment *actOnText(SourceLocation LocBegin,
145                          SourceLocation LocEnd,
146                          StringRef Text);
147 
148   VerbatimBlockComment *actOnVerbatimBlockStart(SourceLocation Loc,
149                                                 unsigned CommandID);
150 
151   VerbatimBlockLineComment *actOnVerbatimBlockLine(SourceLocation Loc,
152                                                    StringRef Text);
153 
154   void actOnVerbatimBlockFinish(VerbatimBlockComment *Block,
155                                 SourceLocation CloseNameLocBegin,
156                                 StringRef CloseName,
157                                 ArrayRef<VerbatimBlockLineComment *> Lines);
158 
159   VerbatimLineComment *actOnVerbatimLine(SourceLocation LocBegin,
160                                          unsigned CommandID,
161                                          SourceLocation TextBegin,
162                                          StringRef Text);
163 
164   HTMLStartTagComment *actOnHTMLStartTagStart(SourceLocation LocBegin,
165                                               StringRef TagName);
166 
167   void actOnHTMLStartTagFinish(HTMLStartTagComment *Tag,
168                                ArrayRef<HTMLStartTagComment::Attribute> Attrs,
169                                SourceLocation GreaterLoc,
170                                bool IsSelfClosing);
171 
172   HTMLEndTagComment *actOnHTMLEndTag(SourceLocation LocBegin,
173                                      SourceLocation LocEnd,
174                                      StringRef TagName);
175 
176   FullComment *actOnFullComment(ArrayRef<BlockContentComment *> Blocks);
177 
178 private:
179   void checkBlockCommandEmptyParagraph(BlockCommandComment *Command);
180 
181   void checkReturnsCommand(const BlockCommandComment *Command);
182 
183   /// Emit diagnostics about duplicate block commands that should be
184   /// used only once per comment, e.g., \and \\returns.
185   void checkBlockCommandDuplicate(const BlockCommandComment *Command);
186 
187   void checkDeprecatedCommand(const BlockCommandComment *Comment);
188 
189   void checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment);
190 
191   void checkContainerDeclVerbatimLine(const BlockCommandComment *Comment);
192 
193   void checkContainerDecl(const BlockCommandComment *Comment);
194 
195   /// Resolve parameter names to parameter indexes in function declaration.
196   /// Emit diagnostics about unknown parameters.
197   void resolveParamCommandIndexes(const FullComment *FC);
198 
199   /// \returns \c true if the declaration that this comment is attached to
200   /// is a pointer to function/method/block type or has such a type.
201   bool involvesFunctionType();
202 
203   bool isFunctionDecl();
204   bool isAnyFunctionDecl();
205 
206   /// \returns \c true if declaration that this comment is attached to declares
207   /// a function pointer.
208   bool isFunctionPointerVarDecl();
209   bool isFunctionOrMethodVariadic();
210   bool isObjCMethodDecl();
211   bool isObjCPropertyDecl();
212   bool isTemplateOrSpecialization();
213   bool isRecordLikeDecl();
214   bool isClassOrStructDecl();
215   /// \return \c true if the declaration that this comment is attached to
216   /// declares either struct, class or tag typedef.
217   bool isClassOrStructOrTagTypedefDecl();
218   bool isUnionDecl();
219   bool isObjCInterfaceDecl();
220   bool isObjCProtocolDecl();
221   bool isClassTemplateDecl();
222   bool isFunctionTemplateDecl();
223 
224   ArrayRef<const ParmVarDecl *> getParamVars();
225 
226   /// Extract all important semantic information from
227   /// \c ThisDeclInfo->ThisDecl into \c ThisDeclInfo members.
228   void inspectThisDecl();
229 
230   /// Returns index of a function parameter with a given name.
231   unsigned resolveParmVarReference(StringRef Name,
232                                    ArrayRef<const ParmVarDecl *> ParamVars);
233 
234   /// Returns index of a function parameter with the name closest to a given
235   /// typo.
236   unsigned correctTypoInParmVarReference(StringRef Typo,
237                                          ArrayRef<const ParmVarDecl *> ParamVars);
238 
239   bool resolveTParamReference(StringRef Name,
240                               const TemplateParameterList *TemplateParameters,
241                               SmallVectorImpl<unsigned> *Position);
242 
243   StringRef correctTypoInTParamReference(
244                               StringRef Typo,
245                               const TemplateParameterList *TemplateParameters);
246 
247   InlineCommandRenderKind getInlineCommandRenderKind(StringRef Name) const;
248 };
249 
250 } // end namespace comments
251 } // end namespace clang
252 
253 #endif
254 
255