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