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 None; 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 135 InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin, 136 SourceLocation CommandLocEnd, 137 unsigned CommandID, 138 SourceLocation ArgLocBegin, 139 SourceLocation ArgLocEnd, 140 StringRef Arg); 141 142 InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin, 143 SourceLocation LocEnd, 144 StringRef CommandName); 145 146 InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin, 147 SourceLocation LocEnd, 148 unsigned CommandID); 149 150 TextComment *actOnText(SourceLocation LocBegin, 151 SourceLocation LocEnd, 152 StringRef Text); 153 154 VerbatimBlockComment *actOnVerbatimBlockStart(SourceLocation Loc, 155 unsigned CommandID); 156 157 VerbatimBlockLineComment *actOnVerbatimBlockLine(SourceLocation Loc, 158 StringRef Text); 159 160 void actOnVerbatimBlockFinish(VerbatimBlockComment *Block, 161 SourceLocation CloseNameLocBegin, 162 StringRef CloseName, 163 ArrayRef<VerbatimBlockLineComment *> Lines); 164 165 VerbatimLineComment *actOnVerbatimLine(SourceLocation LocBegin, 166 unsigned CommandID, 167 SourceLocation TextBegin, 168 StringRef Text); 169 170 HTMLStartTagComment *actOnHTMLStartTagStart(SourceLocation LocBegin, 171 StringRef TagName); 172 173 void actOnHTMLStartTagFinish(HTMLStartTagComment *Tag, 174 ArrayRef<HTMLStartTagComment::Attribute> Attrs, 175 SourceLocation GreaterLoc, 176 bool IsSelfClosing); 177 178 HTMLEndTagComment *actOnHTMLEndTag(SourceLocation LocBegin, 179 SourceLocation LocEnd, 180 StringRef TagName); 181 182 FullComment *actOnFullComment(ArrayRef<BlockContentComment *> Blocks); 183 184 void checkBlockCommandEmptyParagraph(BlockCommandComment *Command); 185 186 void checkReturnsCommand(const BlockCommandComment *Command); 187 188 /// Emit diagnostics about duplicate block commands that should be 189 /// used only once per comment, e.g., \and \\returns. 190 void checkBlockCommandDuplicate(const BlockCommandComment *Command); 191 192 void checkDeprecatedCommand(const BlockCommandComment *Comment); 193 194 void checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment); 195 196 void checkContainerDeclVerbatimLine(const BlockCommandComment *Comment); 197 198 void checkContainerDecl(const BlockCommandComment *Comment); 199 200 /// Resolve parameter names to parameter indexes in function declaration. 201 /// Emit diagnostics about unknown parametrs. 202 void resolveParamCommandIndexes(const FullComment *FC); 203 204 bool isFunctionDecl(); 205 bool isAnyFunctionDecl(); 206 207 /// \returns \c true if declaration that this comment is attached to declares 208 /// a function pointer. 209 bool isFunctionPointerVarDecl(); 210 /// \returns \c true if the declaration that this comment is attached to 211 /// declares a variable or a field whose type is a function or a block 212 /// pointer. 213 bool isFunctionOrBlockPointerVarLikeDecl(); 214 bool isFunctionOrMethodVariadic(); 215 bool isObjCMethodDecl(); 216 bool isObjCPropertyDecl(); 217 bool isTemplateOrSpecialization(); 218 bool isRecordLikeDecl(); 219 bool isClassOrStructDecl(); 220 /// \return \c true if the declaration that this comment is attached to 221 /// declares either struct, class or tag typedef. 222 bool isClassOrStructOrTagTypedefDecl(); 223 bool isUnionDecl(); 224 bool isObjCInterfaceDecl(); 225 bool isObjCProtocolDecl(); 226 bool isClassTemplateDecl(); 227 bool isFunctionTemplateDecl(); 228 229 ArrayRef<const ParmVarDecl *> getParamVars(); 230 231 /// Extract all important semantic information from 232 /// \c ThisDeclInfo->ThisDecl into \c ThisDeclInfo members. 233 void inspectThisDecl(); 234 235 /// Returns index of a function parameter with a given name. 236 unsigned resolveParmVarReference(StringRef Name, 237 ArrayRef<const ParmVarDecl *> ParamVars); 238 239 /// Returns index of a function parameter with the name closest to a given 240 /// typo. 241 unsigned correctTypoInParmVarReference(StringRef Typo, 242 ArrayRef<const ParmVarDecl *> ParamVars); 243 244 bool resolveTParamReference(StringRef Name, 245 const TemplateParameterList *TemplateParameters, 246 SmallVectorImpl<unsigned> *Position); 247 248 StringRef correctTypoInTParamReference( 249 StringRef Typo, 250 const TemplateParameterList *TemplateParameters); 251 252 InlineCommandComment::RenderKind 253 getInlineCommandRenderKind(StringRef Name) const; 254 }; 255 256 } // end namespace comments 257 } // end namespace clang 258 259 #endif 260 261