18#include "llvm/ADT/StringSwitch.h"
24#include "clang/AST/CommentHTMLTagsProperties.inc"
27Sema::Sema(llvm::BumpPtrAllocator &Allocator,
const SourceManager &SourceMgr,
30 Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags), Traits(Traits),
31 PP(PP), ThisDeclInfo(nullptr), BriefCommand(nullptr),
32 HeaderfileCommand(nullptr) {
39 ThisDeclInfo =
new (Allocator)
DeclInfo;
57 checkContainerDecl(BC);
69 checkBlockCommandEmptyParagraph(Command);
70 checkBlockCommandDuplicate(Command);
74 checkReturnsCommand(Command);
75 checkDeprecatedCommand(Command);
88 if (!involvesFunctionType())
90 diag::warn_doc_param_not_attached_to_a_function_decl)
103 switch (
Comment->getCommandID()) {
104 case CommandTraits::KCI_function:
105 DiagSelect = (!isAnyFunctionDecl() && !isFunctionTemplateDecl())? 1 : 0;
107 case CommandTraits::KCI_functiongroup:
108 DiagSelect = (!isAnyFunctionDecl() && !isFunctionTemplateDecl())? 2 : 0;
110 case CommandTraits::KCI_method:
111 DiagSelect = !isObjCMethodDecl() ? 3 : 0;
113 case CommandTraits::KCI_methodgroup:
114 DiagSelect = !isObjCMethodDecl() ? 4 : 0;
116 case CommandTraits::KCI_callback:
117 DiagSelect = !isFunctionPointerVarDecl() ? 5 : 0;
124 Diag(Comment->
getLocation(), diag::warn_doc_function_method_decl_mismatch)
126 << (DiagSelect-1) << (DiagSelect-1)
130void Sema::checkContainerDeclVerbatimLine(
const BlockCommandComment *Comment) {
131 const CommandInfo *Info = Traits.
getCommandInfo(Comment->getCommandID());
132 if (!Info->IsRecordLikeDeclarationCommand)
135 switch (Comment->getCommandID()) {
136 case CommandTraits::KCI_class:
138 (!isClassOrStructOrTagTypedefDecl() && !isClassTemplateDecl()) ? 1
143 if (DiagSelect && Comment->getCommandMarker() && isObjCInterfaceDecl())
146 case CommandTraits::KCI_interface:
147 DiagSelect = !isObjCInterfaceDecl() ? 2 : 0;
149 case CommandTraits::KCI_protocol:
150 DiagSelect = !isObjCProtocolDecl() ? 3 : 0;
152 case CommandTraits::KCI_struct:
153 DiagSelect = !isClassOrStructOrTagTypedefDecl() ? 4 : 0;
155 case CommandTraits::KCI_union:
156 DiagSelect = !isUnionDecl() ? 5 : 0;
163 Diag(Comment->getLocation(), diag::warn_doc_api_container_decl_mismatch)
164 << Comment->getCommandMarker()
165 << (DiagSelect-1) << (DiagSelect-1)
166 << Comment->getSourceRange();
169void Sema::checkContainerDecl(
const BlockCommandComment *Comment) {
170 const CommandInfo *Info = Traits.
getCommandInfo(Comment->getCommandID());
171 if (!Info->IsRecordLikeDetailCommand || isRecordLikeDecl())
174 switch (Comment->getCommandID()) {
175 case CommandTraits::KCI_classdesign:
178 case CommandTraits::KCI_coclass:
181 case CommandTraits::KCI_dependency:
184 case CommandTraits::KCI_helper:
187 case CommandTraits::KCI_helperclass:
190 case CommandTraits::KCI_helps:
193 case CommandTraits::KCI_instancesize:
196 case CommandTraits::KCI_ownership:
199 case CommandTraits::KCI_performance:
202 case CommandTraits::KCI_security:
205 case CommandTraits::KCI_superclass:
213 Diag(Comment->getLocation(), diag::warn_doc_container_decl_mismatch)
214 << Comment->getCommandMarker()
216 << Comment->getSourceRange();
222 return llvm::StringSwitch<ParamCommandPassDirection>(Arg)
233 std::string ArgLower = Arg.lower();
243 const char *FixedName =
245 Diag(ArgLocBegin, diag::warn_doc_param_spaces_in_direction)
248 Diag(ArgLocBegin, diag::warn_doc_param_invalid_direction) << ArgRange;
268 auto *A =
new (Allocator)
276 checkBlockCommandEmptyParagraph(Command);
288 if (!isTemplateOrSpecialization())