1ca76bf8a935ef1da970fbc95869e899120883ba1Fariborz Jahanian//===--- CommentSema.cpp - Doxygen comment semantic analysis --------------===// 28d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko// 38d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko// The LLVM Compiler Infrastructure 48d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko// 58d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko// This file is distributed under the University of Illinois Open Source 68d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko// License. See LICENSE.TXT for details. 78d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko// 88d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko//===----------------------------------------------------------------------===// 98d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 108d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#include "clang/AST/CommentSema.h" 112fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "clang/AST/Attr.h" 12aa58081902ad31927df02e8537d972eabe29d6dfDmitri Gribenko#include "clang/AST/CommentCommandTraits.h" 132fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "clang/AST/CommentDiagnostic.h" 14a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko#include "clang/AST/Decl.h" 1596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko#include "clang/AST/DeclTemplate.h" 16a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko#include "clang/Basic/SourceManager.h" 171952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko#include "clang/Lex/Preprocessor.h" 181952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko#include "llvm/ADT/SmallString.h" 1955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/ADT/StringSwitch.h" 208d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 218d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenkonamespace clang { 228d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenkonamespace comments { 238d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 24c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenkonamespace { 25c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko#include "clang/AST/CommentHTMLTagsProperties.inc" 26c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko} // unnamed namespace 27c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko 28a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri GribenkoSema::Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr, 291952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko DiagnosticsEngine &Diags, CommandTraits &Traits, 301952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko const Preprocessor *PP) : 31aa58081902ad31927df02e8537d972eabe29d6dfDmitri Gribenko Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags), Traits(Traits), 3297e5bc2643dd1478ca10d1b9a6581f332801c958Dmitri Gribenko PP(PP), ThisDeclInfo(NULL), BriefCommand(NULL), HeaderfileCommand(NULL) { 33a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko} 34a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 35a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenkovoid Sema::setDecl(const Decl *D) { 361ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko if (!D) 371ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko return; 381ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko 391ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko ThisDeclInfo = new (Allocator) DeclInfo; 40bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian ThisDeclInfo->CommentDecl = D; 41651f8ce530ebe6f7f4b67988c3c532a94f097efcDmitri Gribenko ThisDeclInfo->IsFilled = false; 428d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 438d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 448d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoParagraphComment *Sema::actOnParagraphComment( 458d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko ArrayRef<InlineContentComment *> Content) { 468d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko return new (Allocator) ParagraphComment(Content); 478d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 488d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 49808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri GribenkoBlockCommandComment *Sema::actOnBlockCommandStart( 50808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko SourceLocation LocBegin, 51808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko SourceLocation LocEnd, 52808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko unsigned CommandID, 53808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko CommandMarkerKind CommandMarker) { 5428c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian BlockCommandComment *BC = new (Allocator) BlockCommandComment(LocBegin, LocEnd, 5528c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian CommandID, 5628c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian CommandMarker); 5728c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian checkContainerDecl(BC); 5828c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return BC; 598d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 608d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 617d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenkovoid Sema::actOnBlockCommandArgs(BlockCommandComment *Command, 627d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko ArrayRef<BlockCommandComment::Argument> Args) { 638d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Command->setArgs(Args); 648d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 658d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 667d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenkovoid Sema::actOnBlockCommandFinish(BlockCommandComment *Command, 677d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko ParagraphComment *Paragraph) { 688d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Command->setParagraph(Paragraph); 69a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko checkBlockCommandEmptyParagraph(Command); 709443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko checkBlockCommandDuplicate(Command); 7189ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko checkReturnsCommand(Command); 720bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko checkDeprecatedCommand(Command); 738d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 748d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 75808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri GribenkoParamCommandComment *Sema::actOnParamCommandStart( 76808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko SourceLocation LocBegin, 77808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko SourceLocation LocEnd, 78808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko unsigned CommandID, 79808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko CommandMarkerKind CommandMarker) { 80a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko ParamCommandComment *Command = 81808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko new (Allocator) ParamCommandComment(LocBegin, LocEnd, CommandID, 82808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko CommandMarker); 83a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 848487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko if (!isFunctionDecl()) 85a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Diag(Command->getLocation(), 86a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko diag::warn_doc_param_not_attached_to_a_function_decl) 87808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko << CommandMarker 88e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Command->getCommandNameRange(Traits); 89a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 90a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko return Command; 918d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 928d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 932a268f2629b49958427e8eb02f2c3d565be71accFariborz Jahanianvoid Sema::checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment) { 942a268f2629b49958427e8eb02f2c3d565be71accFariborz Jahanian const CommandInfo *Info = Traits.getCommandInfo(Comment->getCommandID()); 9599a7057098c56211e641705e1ff38d4b7c8b309dFariborz Jahanian if (!Info->IsFunctionDeclarationCommand) 9699a7057098c56211e641705e1ff38d4b7c8b309dFariborz Jahanian return; 97b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian 98b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian unsigned DiagSelect; 99b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian switch (Comment->getCommandID()) { 100b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_function: 1012d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian DiagSelect = (!isAnyFunctionDecl() && !isFunctionTemplateDecl())? 1 : 0; 102b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 1032aa5cf412c9a56aba1e3a7b04ca18499a2b83b20Fariborz Jahanian case CommandTraits::KCI_functiongroup: 1042d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian DiagSelect = (!isAnyFunctionDecl() && !isFunctionTemplateDecl())? 2 : 0; 1052aa5cf412c9a56aba1e3a7b04ca18499a2b83b20Fariborz Jahanian break; 106b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_method: 1072aa5cf412c9a56aba1e3a7b04ca18499a2b83b20Fariborz Jahanian DiagSelect = !isObjCMethodDecl() ? 3 : 0; 1082aa5cf412c9a56aba1e3a7b04ca18499a2b83b20Fariborz Jahanian break; 1092aa5cf412c9a56aba1e3a7b04ca18499a2b83b20Fariborz Jahanian case CommandTraits::KCI_methodgroup: 1102aa5cf412c9a56aba1e3a7b04ca18499a2b83b20Fariborz Jahanian DiagSelect = !isObjCMethodDecl() ? 4 : 0; 111b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 112b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_callback: 1132aa5cf412c9a56aba1e3a7b04ca18499a2b83b20Fariborz Jahanian DiagSelect = !isFunctionPointerVarDecl() ? 5 : 0; 114b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 115b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian default: 116b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 0; 117b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 118b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian } 11988f070f99f7f352e294eed212fdf7a23c0815fe2Fariborz Jahanian if (DiagSelect) 12088f070f99f7f352e294eed212fdf7a23c0815fe2Fariborz Jahanian Diag(Comment->getLocation(), diag::warn_doc_function_method_decl_mismatch) 12188f070f99f7f352e294eed212fdf7a23c0815fe2Fariborz Jahanian << Comment->getCommandMarker() 12288f070f99f7f352e294eed212fdf7a23c0815fe2Fariborz Jahanian << (DiagSelect-1) << (DiagSelect-1) 1232a268f2629b49958427e8eb02f2c3d565be71accFariborz Jahanian << Comment->getSourceRange(); 1242a268f2629b49958427e8eb02f2c3d565be71accFariborz Jahanian} 12528c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian 12628c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanianvoid Sema::checkContainerDeclVerbatimLine(const BlockCommandComment *Comment) { 12728c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian const CommandInfo *Info = Traits.getCommandInfo(Comment->getCommandID()); 128b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian if (!Info->IsRecordLikeDeclarationCommand) 12928c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return; 130b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian unsigned DiagSelect; 131b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian switch (Comment->getCommandID()) { 132b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_class: 1332d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian DiagSelect = (!isClassOrStructDecl() && !isClassTemplateDecl()) ? 1 : 0; 134dbed7cceb8b453cc0ef78cc83f5466d5268037baFariborz Jahanian // Allow @class command on @interface declarations. 135dbed7cceb8b453cc0ef78cc83f5466d5268037baFariborz Jahanian // FIXME. Currently, \class and @class are indistinguishable. So, 136dbed7cceb8b453cc0ef78cc83f5466d5268037baFariborz Jahanian // \class is also allowed on an @interface declaration 137dbed7cceb8b453cc0ef78cc83f5466d5268037baFariborz Jahanian if (DiagSelect && Comment->getCommandMarker() && isObjCInterfaceDecl()) 138dbed7cceb8b453cc0ef78cc83f5466d5268037baFariborz Jahanian DiagSelect = 0; 139b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 140b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_interface: 141b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = !isObjCInterfaceDecl() ? 2 : 0; 142b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 143b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_protocol: 144b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = !isObjCProtocolDecl() ? 3 : 0; 145b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 146b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_struct: 147b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = !isClassOrStructDecl() ? 4 : 0; 148b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 149b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_union: 150b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = !isUnionDecl() ? 5 : 0; 151b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 152b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian default: 153b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 0; 154b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 155b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian } 15628c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (DiagSelect) 15728c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian Diag(Comment->getLocation(), diag::warn_doc_api_container_decl_mismatch) 15828c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian << Comment->getCommandMarker() 15928c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian << (DiagSelect-1) << (DiagSelect-1) 16028c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian << Comment->getSourceRange(); 16128c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian} 16228c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian 16328c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanianvoid Sema::checkContainerDecl(const BlockCommandComment *Comment) { 16428c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian const CommandInfo *Info = Traits.getCommandInfo(Comment->getCommandID()); 165b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian if (!Info->IsRecordLikeDetailCommand || isRecordLikeDecl()) 16628c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return; 167b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian unsigned DiagSelect; 168b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian switch (Comment->getCommandID()) { 169b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_classdesign: 170b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 1; 171b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 172b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_coclass: 173b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 2; 174b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 175b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_dependency: 176b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 3; 177b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 178b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_helper: 179b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 4; 180b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 181b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_helperclass: 182b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 5; 183b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 184b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_helps: 185b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 6; 186b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 187b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_instancesize: 188b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 7; 189b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 190b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_ownership: 191b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 8; 192b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 193b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_performance: 194b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 9; 195b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 196b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_security: 197b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 10; 198b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 199b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_superclass: 200b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 11; 201b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 202b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian default: 203b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 0; 204b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 205b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian } 20628c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (DiagSelect) 20728c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian Diag(Comment->getLocation(), diag::warn_doc_container_decl_mismatch) 20828c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian << Comment->getCommandMarker() 20928c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian << (DiagSelect-1) 21028c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian << Comment->getSourceRange(); 21128c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian} 2122a268f2629b49958427e8eb02f2c3d565be71accFariborz Jahanian 2137d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenkovoid Sema::actOnParamCommandDirectionArg(ParamCommandComment *Command, 2147d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko SourceLocation ArgLocBegin, 2157d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko SourceLocation ArgLocEnd, 2167d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko StringRef Arg) { 217a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko ParamCommandComment::PassDirection Direction; 218a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko std::string ArgLower = Arg.lower(); 219a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko // TODO: optimize: lower Name first (need an API in SmallString for that), 220a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko // after that StringSwitch. 221a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (ArgLower == "[in]") 222a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Direction = ParamCommandComment::In; 223a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko else if (ArgLower == "[out]") 224a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Direction = ParamCommandComment::Out; 225a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko else if (ArgLower == "[in,out]" || ArgLower == "[out,in]") 226a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Direction = ParamCommandComment::InOut; 227a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko else { 228a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko // Remove spaces. 229a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko std::string::iterator O = ArgLower.begin(); 230a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko for (std::string::iterator I = ArgLower.begin(), E = ArgLower.end(); 231a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko I != E; ++I) { 232a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko const char C = *I; 233a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (C != ' ' && C != '\n' && C != '\r' && 234a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko C != '\t' && C != '\v' && C != '\f') 235a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko *O++ = C; 236a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 237a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko ArgLower.resize(O - ArgLower.begin()); 238a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 239a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko bool RemovingWhitespaceHelped = false; 240a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (ArgLower == "[in]") { 2418d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Direction = ParamCommandComment::In; 242a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko RemovingWhitespaceHelped = true; 243a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } else if (ArgLower == "[out]") { 2448d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Direction = ParamCommandComment::Out; 245a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko RemovingWhitespaceHelped = true; 246a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } else if (ArgLower == "[in,out]" || ArgLower == "[out,in]") { 2478d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Direction = ParamCommandComment::InOut; 248a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko RemovingWhitespaceHelped = true; 2498d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko } else { 250a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Direction = ParamCommandComment::In; 251a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko RemovingWhitespaceHelped = false; 2528d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko } 253a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 254a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko SourceRange ArgRange(ArgLocBegin, ArgLocEnd); 255a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (RemovingWhitespaceHelped) 256a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Diag(ArgLocBegin, diag::warn_doc_param_spaces_in_direction) 257a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko << ArgRange 258a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko << FixItHint::CreateReplacement( 259a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko ArgRange, 260a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko ParamCommandComment::getDirectionAsString(Direction)); 261a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko else 262a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Diag(ArgLocBegin, diag::warn_doc_param_invalid_direction) 263a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko << ArgRange; 2648d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko } 265a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Command->setDirection(Direction, /* Explicit = */ true); 266a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko} 267a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 2687d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenkovoid Sema::actOnParamCommandParamNameArg(ParamCommandComment *Command, 2697d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko SourceLocation ArgLocBegin, 2707d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko SourceLocation ArgLocEnd, 2717d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko StringRef Arg) { 272a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko // Parser will not feed us more arguments than needed. 2730eaf69d9a10149f0f344238183915912c2dca392Dmitri Gribenko assert(Command->getNumArgs() == 0); 274a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 275a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (!Command->isDirectionExplicit()) { 276a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko // User didn't provide a direction argument. 277a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Command->setDirection(ParamCommandComment::In, /* Explicit = */ false); 278a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 279a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko typedef BlockCommandComment::Argument Argument; 280a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Argument *A = new (Allocator) Argument(SourceRange(ArgLocBegin, 281a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko ArgLocEnd), 282a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Arg); 283a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Command->setArgs(llvm::makeArrayRef(A, 1)); 2848d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 2858d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 2867d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenkovoid Sema::actOnParamCommandFinish(ParamCommandComment *Command, 2877d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko ParagraphComment *Paragraph) { 2888d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Command->setParagraph(Paragraph); 289a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko checkBlockCommandEmptyParagraph(Command); 2908d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 2918d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 292808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri GribenkoTParamCommandComment *Sema::actOnTParamCommandStart( 293808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko SourceLocation LocBegin, 294808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko SourceLocation LocEnd, 295808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko unsigned CommandID, 296808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko CommandMarkerKind CommandMarker) { 29796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko TParamCommandComment *Command = 298808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko new (Allocator) TParamCommandComment(LocBegin, LocEnd, CommandID, 299808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko CommandMarker); 30096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 30104bf29eb1b197e0a103139ab5d63b0b97432f004Dmitri Gribenko if (!isTemplateOrSpecialization()) 30296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Diag(Command->getLocation(), 30396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko diag::warn_doc_tparam_not_attached_to_a_template_decl) 304808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko << CommandMarker 305e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Command->getCommandNameRange(Traits); 30696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 30796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return Command; 30896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} 30996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 3107d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenkovoid Sema::actOnTParamCommandParamNameArg(TParamCommandComment *Command, 3117d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko SourceLocation ArgLocBegin, 3127d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko SourceLocation ArgLocEnd, 3137d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko StringRef Arg) { 31496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko // Parser will not feed us more arguments than needed. 31596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko assert(Command->getNumArgs() == 0); 31696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 31796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko typedef BlockCommandComment::Argument Argument; 31896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Argument *A = new (Allocator) Argument(SourceRange(ArgLocBegin, 31996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko ArgLocEnd), 32096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Arg); 32196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Command->setArgs(llvm::makeArrayRef(A, 1)); 32296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 32304bf29eb1b197e0a103139ab5d63b0b97432f004Dmitri Gribenko if (!isTemplateOrSpecialization()) { 32496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko // We already warned that this \\tparam is not attached to a template decl. 3257d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko return; 32696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 32796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 3281ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko const TemplateParameterList *TemplateParameters = 3291ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko ThisDeclInfo->TemplateParameters; 33096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko SmallVector<unsigned, 2> Position; 33196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (resolveTParamReference(Arg, TemplateParameters, &Position)) { 33296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Command->setPosition(copyArray(llvm::makeArrayRef(Position))); 33396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko llvm::StringMap<TParamCommandComment *>::iterator PrevCommandIt = 33496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko TemplateParameterDocs.find(Arg); 33596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (PrevCommandIt != TemplateParameterDocs.end()) { 33696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko SourceRange ArgRange(ArgLocBegin, ArgLocEnd); 33796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Diag(ArgLocBegin, diag::warn_doc_tparam_duplicate) 33896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko << Arg << ArgRange; 33996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko TParamCommandComment *PrevCommand = PrevCommandIt->second; 34096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Diag(PrevCommand->getLocation(), diag::note_doc_tparam_previous) 34196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko << PrevCommand->getParamNameRange(); 34296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 34396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko TemplateParameterDocs[Arg] = Command; 3447d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko return; 34596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 34696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 34796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko SourceRange ArgRange(ArgLocBegin, ArgLocEnd); 34896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Diag(ArgLocBegin, diag::warn_doc_tparam_not_found) 34996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko << Arg << ArgRange; 35096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 35196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (!TemplateParameters || TemplateParameters->size() == 0) 3527d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko return; 35396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 35496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko StringRef CorrectedName; 35596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (TemplateParameters->size() == 1) { 35696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const NamedDecl *Param = TemplateParameters->getParam(0); 35796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const IdentifierInfo *II = Param->getIdentifier(); 35896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (II) 35996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko CorrectedName = II->getName(); 36096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } else { 36196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko CorrectedName = correctTypoInTParamReference(Arg, TemplateParameters); 36296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 36396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 36496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (!CorrectedName.empty()) { 36596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Diag(ArgLocBegin, diag::note_doc_tparam_name_suggestion) 36696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko << CorrectedName 36796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko << FixItHint::CreateReplacement(ArgRange, CorrectedName); 36896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 36996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 3707d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko return; 37196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} 37296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 3737d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenkovoid Sema::actOnTParamCommandFinish(TParamCommandComment *Command, 3747d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko ParagraphComment *Paragraph) { 37596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Command->setParagraph(Paragraph); 37696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko checkBlockCommandEmptyParagraph(Command); 37796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} 37896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 3798d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoInlineCommandComment *Sema::actOnInlineCommand(SourceLocation CommandLocBegin, 3808d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko SourceLocation CommandLocEnd, 381e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko unsigned CommandID) { 3828d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko ArrayRef<InlineCommandComment::Argument> Args; 383e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko StringRef CommandName = Traits.getCommandInfo(CommandID)->Name; 3842d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko return new (Allocator) InlineCommandComment( 3852d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko CommandLocBegin, 3862d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko CommandLocEnd, 387e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko CommandID, 3882d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko getInlineCommandRenderKind(CommandName), 3892d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko Args); 3908d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 3918d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 3928d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoInlineCommandComment *Sema::actOnInlineCommand(SourceLocation CommandLocBegin, 3938d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko SourceLocation CommandLocEnd, 394e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko unsigned CommandID, 3958d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko SourceLocation ArgLocBegin, 3968d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko SourceLocation ArgLocEnd, 3978d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko StringRef Arg) { 3988d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko typedef InlineCommandComment::Argument Argument; 3998d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Argument *A = new (Allocator) Argument(SourceRange(ArgLocBegin, 4008d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko ArgLocEnd), 4018d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Arg); 402e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko StringRef CommandName = Traits.getCommandInfo(CommandID)->Name; 4038d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 4042d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko return new (Allocator) InlineCommandComment( 4052d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko CommandLocBegin, 4062d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko CommandLocEnd, 407e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko CommandID, 4082d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko getInlineCommandRenderKind(CommandName), 4092d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko llvm::makeArrayRef(A, 1)); 4108d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 4118d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 4128d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoInlineContentComment *Sema::actOnUnknownCommand(SourceLocation LocBegin, 4138d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko SourceLocation LocEnd, 414b0b8a96df25660cbdbf35d23c3ff5887c33f82f9Dmitri Gribenko StringRef CommandName) { 415b0b8a96df25660cbdbf35d23c3ff5887c33f82f9Dmitri Gribenko unsigned CommandID = Traits.registerUnknownCommand(CommandName)->getID(); 416b0b8a96df25660cbdbf35d23c3ff5887c33f82f9Dmitri Gribenko return actOnUnknownCommand(LocBegin, LocEnd, CommandID); 417b0b8a96df25660cbdbf35d23c3ff5887c33f82f9Dmitri Gribenko} 418b0b8a96df25660cbdbf35d23c3ff5887c33f82f9Dmitri Gribenko 419b0b8a96df25660cbdbf35d23c3ff5887c33f82f9Dmitri GribenkoInlineContentComment *Sema::actOnUnknownCommand(SourceLocation LocBegin, 420b0b8a96df25660cbdbf35d23c3ff5887c33f82f9Dmitri Gribenko SourceLocation LocEnd, 421b0b8a96df25660cbdbf35d23c3ff5887c33f82f9Dmitri Gribenko unsigned CommandID) { 4228d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko ArrayRef<InlineCommandComment::Argument> Args; 4232d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko return new (Allocator) InlineCommandComment( 424e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko LocBegin, LocEnd, CommandID, 4252d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko InlineCommandComment::RenderNormal, 4262d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko Args); 4278d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 4288d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 4298d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoTextComment *Sema::actOnText(SourceLocation LocBegin, 4308d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko SourceLocation LocEnd, 4318d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko StringRef Text) { 4328d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko return new (Allocator) TextComment(LocBegin, LocEnd, Text); 4338d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 4348d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 4358d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoVerbatimBlockComment *Sema::actOnVerbatimBlockStart(SourceLocation Loc, 436e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko unsigned CommandID) { 437e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko StringRef CommandName = Traits.getCommandInfo(CommandID)->Name; 4388d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko return new (Allocator) VerbatimBlockComment( 4398d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Loc, 440e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko Loc.getLocWithOffset(1 + CommandName.size()), 441e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko CommandID); 4428d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 4438d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 4448d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoVerbatimBlockLineComment *Sema::actOnVerbatimBlockLine(SourceLocation Loc, 4458d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko StringRef Text) { 4468d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko return new (Allocator) VerbatimBlockLineComment(Loc, Text); 4478d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 4488d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 4497d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenkovoid Sema::actOnVerbatimBlockFinish( 4508d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko VerbatimBlockComment *Block, 4518d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko SourceLocation CloseNameLocBegin, 4528d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko StringRef CloseName, 4538d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko ArrayRef<VerbatimBlockLineComment *> Lines) { 4548d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Block->setCloseName(CloseName, CloseNameLocBegin); 4558d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Block->setLines(Lines); 4568d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 4578d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 4588d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoVerbatimLineComment *Sema::actOnVerbatimLine(SourceLocation LocBegin, 459e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko unsigned CommandID, 4608d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko SourceLocation TextBegin, 4618d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko StringRef Text) { 462bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian VerbatimLineComment *VL = new (Allocator) VerbatimLineComment( 4638d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko LocBegin, 4648d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko TextBegin.getLocWithOffset(Text.size()), 465e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko CommandID, 4668d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko TextBegin, 4678d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Text); 468bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian checkFunctionDeclVerbatimLine(VL); 46928c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian checkContainerDeclVerbatimLine(VL); 470bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian return VL; 4718d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 4728d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 4733f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri GribenkoHTMLStartTagComment *Sema::actOnHTMLStartTagStart(SourceLocation LocBegin, 4743f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko StringRef TagName) { 4753f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko return new (Allocator) HTMLStartTagComment(LocBegin, TagName); 4768d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 4778d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 4787d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenkovoid Sema::actOnHTMLStartTagFinish( 4793f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko HTMLStartTagComment *Tag, 4803f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko ArrayRef<HTMLStartTagComment::Attribute> Attrs, 481a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko SourceLocation GreaterLoc, 482a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko bool IsSelfClosing) { 4838d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Tag->setAttrs(Attrs); 4848d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Tag->setGreaterLoc(GreaterLoc); 485a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (IsSelfClosing) 486a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Tag->setSelfClosing(); 4873f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko else if (!isHTMLEndTagForbidden(Tag->getTagName())) 488a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko HTMLOpenTags.push_back(Tag); 4898d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 4908d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 4913f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri GribenkoHTMLEndTagComment *Sema::actOnHTMLEndTag(SourceLocation LocBegin, 4923f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko SourceLocation LocEnd, 4933f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko StringRef TagName) { 4943f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko HTMLEndTagComment *HET = 4953f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko new (Allocator) HTMLEndTagComment(LocBegin, LocEnd, TagName); 4963f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko if (isHTMLEndTagForbidden(TagName)) { 4973f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko Diag(HET->getLocation(), diag::warn_doc_html_end_forbidden) 4983f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko << TagName << HET->getSourceRange(); 4993f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko return HET; 5003d986980bd02594b1a5aa7b9f9f68d201621ced7Dmitri Gribenko } 5013d986980bd02594b1a5aa7b9f9f68d201621ced7Dmitri Gribenko 502a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko bool FoundOpen = false; 5033f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko for (SmallVectorImpl<HTMLStartTagComment *>::const_reverse_iterator 504a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko I = HTMLOpenTags.rbegin(), E = HTMLOpenTags.rend(); 505a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko I != E; ++I) { 506a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if ((*I)->getTagName() == TagName) { 507a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko FoundOpen = true; 508a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko break; 509a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 510a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 511a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (!FoundOpen) { 5123f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko Diag(HET->getLocation(), diag::warn_doc_html_end_unbalanced) 5133f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko << HET->getSourceRange(); 5143f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko return HET; 515a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 516a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 517a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko while (!HTMLOpenTags.empty()) { 5183f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko const HTMLStartTagComment *HST = HTMLOpenTags.back(); 519a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko HTMLOpenTags.pop_back(); 5203f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko StringRef LastNotClosedTagName = HST->getTagName(); 521a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (LastNotClosedTagName == TagName) 522a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko break; 523a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 5243f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko if (isHTMLEndTagOptional(LastNotClosedTagName)) 525a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko continue; 526a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 527a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko bool OpenLineInvalid; 528a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko const unsigned OpenLine = SourceMgr.getPresumedLineNumber( 5293f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko HST->getLocation(), 530a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko &OpenLineInvalid); 531a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko bool CloseLineInvalid; 532a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko const unsigned CloseLine = SourceMgr.getPresumedLineNumber( 5333f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko HET->getLocation(), 534a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko &CloseLineInvalid); 535a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 536a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (OpenLineInvalid || CloseLineInvalid || OpenLine == CloseLine) 5373f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko Diag(HST->getLocation(), diag::warn_doc_html_start_end_mismatch) 5383f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko << HST->getTagName() << HET->getTagName() 5393f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko << HST->getSourceRange() << HET->getSourceRange(); 540a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko else { 5413f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko Diag(HST->getLocation(), diag::warn_doc_html_start_end_mismatch) 5423f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko << HST->getTagName() << HET->getTagName() 5433f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko << HST->getSourceRange(); 5443f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko Diag(HET->getLocation(), diag::note_doc_html_end_tag) 5453f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko << HET->getSourceRange(); 546a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 547a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 548a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 5493f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko return HET; 5508d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 5518d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 5528d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoFullComment *Sema::actOnFullComment( 5538d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko ArrayRef<BlockContentComment *> Blocks) { 554749ace614b6ea1ae11d194a60b18e1e43e1db243Fariborz Jahanian FullComment *FC = new (Allocator) FullComment(Blocks, ThisDeclInfo); 5559edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko resolveParamCommandIndexes(FC); 5569edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko return FC; 5578d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 5588d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 559a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenkovoid Sema::checkBlockCommandEmptyParagraph(BlockCommandComment *Command) { 560abcf0dccc9cd4c802f4e7797bf452c6808d2226fDmitri Gribenko if (Traits.getCommandInfo(Command->getCommandID())->IsEmptyParagraphAllowed) 561abcf0dccc9cd4c802f4e7797bf452c6808d2226fDmitri Gribenko return; 562abcf0dccc9cd4c802f4e7797bf452c6808d2226fDmitri Gribenko 563a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko ParagraphComment *Paragraph = Command->getParagraph(); 564a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (Paragraph->isWhitespace()) { 565a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko SourceLocation DiagLoc; 5660eaf69d9a10149f0f344238183915912c2dca392Dmitri Gribenko if (Command->getNumArgs() > 0) 5670eaf69d9a10149f0f344238183915912c2dca392Dmitri Gribenko DiagLoc = Command->getArgRange(Command->getNumArgs() - 1).getEnd(); 568a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (!DiagLoc.isValid()) 569e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko DiagLoc = Command->getCommandNameRange(Traits).getEnd(); 570a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Diag(DiagLoc, diag::warn_doc_block_command_empty_paragraph) 571808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko << Command->getCommandMarker() 572e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Command->getCommandName(Traits) 573a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko << Command->getSourceRange(); 574a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 575a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko} 576a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 57789ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenkovoid Sema::checkReturnsCommand(const BlockCommandComment *Command) { 578e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko if (!Traits.getCommandInfo(Command->getCommandID())->IsReturnsCommand) 57989ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko return; 58089ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko if (isFunctionDecl()) { 58189ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko if (ThisDeclInfo->ResultType->isVoidType()) { 58289ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko unsigned DiagKind; 583bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian switch (ThisDeclInfo->CommentDecl->getKind()) { 58489ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko default: 58588815f3f81361692dd281000e3e46bf163b2f28bDmitri Gribenko if (ThisDeclInfo->IsObjCMethod) 58688815f3f81361692dd281000e3e46bf163b2f28bDmitri Gribenko DiagKind = 3; 58788815f3f81361692dd281000e3e46bf163b2f28bDmitri Gribenko else 58888815f3f81361692dd281000e3e46bf163b2f28bDmitri Gribenko DiagKind = 0; 58989ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko break; 59089ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko case Decl::CXXConstructor: 59189ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko DiagKind = 1; 59289ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko break; 59389ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko case Decl::CXXDestructor: 59489ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko DiagKind = 2; 59589ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko break; 59689ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko } 59789ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko Diag(Command->getLocation(), 59889ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko diag::warn_doc_returns_attached_to_a_void_function) 599808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko << Command->getCommandMarker() 600e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Command->getCommandName(Traits) 60189ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko << DiagKind 60289ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko << Command->getSourceRange(); 60389ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko } 60489ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko return; 60589ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko } 606664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanian else if (isObjCPropertyDecl()) 607664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanian return; 608664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanian 60989ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko Diag(Command->getLocation(), 61089ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko diag::warn_doc_returns_not_attached_to_a_function_decl) 611808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko << Command->getCommandMarker() 612e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Command->getCommandName(Traits) 61389ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko << Command->getSourceRange(); 61489ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko} 61589ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko 6169443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenkovoid Sema::checkBlockCommandDuplicate(const BlockCommandComment *Command) { 617e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko const CommandInfo *Info = Traits.getCommandInfo(Command->getCommandID()); 6189443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko const BlockCommandComment *PrevCommand = NULL; 619e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko if (Info->IsBriefCommand) { 6209443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko if (!BriefCommand) { 6219443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko BriefCommand = Command; 6229443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko return; 6239443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko } 6249443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko PrevCommand = BriefCommand; 625f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian } else if (Info->IsHeaderfileCommand) { 626f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian if (!HeaderfileCommand) { 627f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian HeaderfileCommand = Command; 628f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian return; 629f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian } 630f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian PrevCommand = HeaderfileCommand; 6319443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko } else { 6329443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko // We don't want to check this command for duplicates. 6339443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko return; 6349443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko } 635e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko StringRef CommandName = Command->getCommandName(Traits); 636e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko StringRef PrevCommandName = PrevCommand->getCommandName(Traits); 6379443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko Diag(Command->getLocation(), diag::warn_doc_block_command_duplicate) 638808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko << Command->getCommandMarker() 639e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << CommandName 6409443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko << Command->getSourceRange(); 641e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko if (CommandName == PrevCommandName) 6429443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko Diag(PrevCommand->getLocation(), diag::note_doc_block_command_previous) 643808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko << PrevCommand->getCommandMarker() 644e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << PrevCommandName 645e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << PrevCommand->getSourceRange(); 6469443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko else 6479443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko Diag(PrevCommand->getLocation(), 6489443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko diag::note_doc_block_command_previous_alias) 649808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko << PrevCommand->getCommandMarker() 650e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << PrevCommandName 651e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << CommandName; 6529443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko} 6539443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko 6540bd9838751384181ff387f2fb346896792b89617Dmitri Gribenkovoid Sema::checkDeprecatedCommand(const BlockCommandComment *Command) { 6550bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko if (!Traits.getCommandInfo(Command->getCommandID())->IsDeprecatedCommand) 6560bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko return; 6570bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko 658bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian const Decl *D = ThisDeclInfo->CommentDecl; 6590bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko if (!D) 6600bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko return; 6610bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko 6620bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko if (D->hasAttr<DeprecatedAttr>() || 6630bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko D->hasAttr<AvailabilityAttr>() || 6640bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko D->hasAttr<UnavailableAttr>()) 6650bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko return; 6660bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko 6670bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko Diag(Command->getLocation(), 6680bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko diag::warn_doc_deprecated_not_sync) 6690bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko << Command->getSourceRange(); 6700bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko 6710bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko // Try to emit a fixit with a deprecation attribute. 6720bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 6730bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko // Don't emit a Fix-It for non-member function definitions. GCC does not 6740bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko // accept attributes on them. 6750bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko const DeclContext *Ctx = FD->getDeclContext(); 6760bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko if ((!Ctx || !Ctx->isRecord()) && 6770bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko FD->doesThisDeclarationHaveABody()) 6780bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko return; 6790bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko 6801952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko StringRef AttributeSpelling = "__attribute__((deprecated))"; 6811952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko if (PP) { 6821952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko TokenValue Tokens[] = { 6831952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko tok::kw___attribute, tok::l_paren, tok::l_paren, 6841952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko PP->getIdentifierInfo("deprecated"), 6851952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko tok::r_paren, tok::r_paren 6861952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko }; 6871952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko StringRef MacroName = PP->getLastMacroWithSpelling(FD->getLocation(), 6881952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko Tokens); 6891952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko if (!MacroName.empty()) 6901952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko AttributeSpelling = MacroName; 6911952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko } 6921952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko 6931952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko SmallString<64> TextToInsert(" "); 6941952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko TextToInsert += AttributeSpelling; 6950bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko Diag(FD->getLocEnd(), 6960bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko diag::note_add_deprecation_attr) 6970bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko << FixItHint::CreateInsertion(FD->getLocEnd().getLocWithOffset(1), 6981952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko TextToInsert); 6990bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko } 7000bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko} 7010bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko 7029edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenkovoid Sema::resolveParamCommandIndexes(const FullComment *FC) { 7039edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko if (!isFunctionDecl()) { 7049edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // We already warned that \\param commands are not attached to a function 7059edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // decl. 7069edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko return; 7079edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko } 7089edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 709cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<ParamCommandComment *, 8> UnresolvedParamCommands; 7109edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7119edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // Comment AST nodes that correspond to \c ParamVars for which we have 7129edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // found a \\param command or NULL if no documentation was found so far. 713cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<ParamCommandComment *, 8> ParamVarDocs; 7149edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7159edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko ArrayRef<const ParmVarDecl *> ParamVars = getParamVars(); 716b0f9314bbe29d09c3ea3f76a257125d1568665c7NAKAMURA Takumi ParamVarDocs.resize(ParamVars.size(), NULL); 7179edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7189edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // First pass over all \\param commands: resolve all parameter names. 7199edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko for (Comment::child_iterator I = FC->child_begin(), E = FC->child_end(); 7209edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko I != E; ++I) { 7219edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko ParamCommandComment *PCC = dyn_cast<ParamCommandComment>(*I); 7229edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko if (!PCC || !PCC->hasParamName()) 7239edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko continue; 724262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian StringRef ParamName = PCC->getParamNameAsWritten(); 7259edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7269edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // Check that referenced parameter name is in the function decl. 7279edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko const unsigned ResolvedParamIndex = resolveParmVarReference(ParamName, 7289edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko ParamVars); 729c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko if (ResolvedParamIndex == ParamCommandComment::VarArgParamIndex) { 730c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko PCC->setIsVarArgParam(); 731c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko continue; 732c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko } 7339edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko if (ResolvedParamIndex == ParamCommandComment::InvalidParamIndex) { 7349edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko UnresolvedParamCommands.push_back(PCC); 7359edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko continue; 7369edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko } 7379edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko PCC->setParamIndex(ResolvedParamIndex); 7389edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko if (ParamVarDocs[ResolvedParamIndex]) { 7399edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko SourceRange ArgRange = PCC->getParamNameRange(); 7409edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko Diag(ArgRange.getBegin(), diag::warn_doc_param_duplicate) 7419edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko << ParamName << ArgRange; 7429edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko ParamCommandComment *PrevCommand = ParamVarDocs[ResolvedParamIndex]; 7439edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko Diag(PrevCommand->getLocation(), diag::note_doc_param_previous) 7449edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko << PrevCommand->getParamNameRange(); 7459edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko } 7469edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko ParamVarDocs[ResolvedParamIndex] = PCC; 7479edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko } 7489edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7499edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // Find parameter declarations that have no corresponding \\param. 750cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<const ParmVarDecl *, 8> OrphanedParamDecls; 7519edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko for (unsigned i = 0, e = ParamVarDocs.size(); i != e; ++i) { 7529edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko if (!ParamVarDocs[i]) 7539edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko OrphanedParamDecls.push_back(ParamVars[i]); 7549edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko } 7559edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7569edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // Second pass over unresolved \\param commands: do typo correction. 7579edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // Suggest corrections from a set of parameter declarations that have no 7589edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // corresponding \\param. 7599edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko for (unsigned i = 0, e = UnresolvedParamCommands.size(); i != e; ++i) { 7609edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko const ParamCommandComment *PCC = UnresolvedParamCommands[i]; 7619edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7629edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko SourceRange ArgRange = PCC->getParamNameRange(); 763262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian StringRef ParamName = PCC->getParamNameAsWritten(); 7649edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko Diag(ArgRange.getBegin(), diag::warn_doc_param_not_found) 7659edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko << ParamName << ArgRange; 7669edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7679edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // All parameters documented -- can't suggest a correction. 7689edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko if (OrphanedParamDecls.size() == 0) 7699edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko continue; 7709edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7719edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko unsigned CorrectedParamIndex = ParamCommandComment::InvalidParamIndex; 7729edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko if (OrphanedParamDecls.size() == 1) { 7739edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // If one parameter is not documented then that parameter is the only 7749edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // possible suggestion. 7759edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko CorrectedParamIndex = 0; 7769edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko } else { 7779edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // Do typo correction. 7789edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko CorrectedParamIndex = correctTypoInParmVarReference(ParamName, 7799edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko OrphanedParamDecls); 7809edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko } 7819edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko if (CorrectedParamIndex != ParamCommandComment::InvalidParamIndex) { 7829edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko const ParmVarDecl *CorrectedPVD = OrphanedParamDecls[CorrectedParamIndex]; 7839edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko if (const IdentifierInfo *CorrectedII = CorrectedPVD->getIdentifier()) 7849edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko Diag(ArgRange.getBegin(), diag::note_doc_param_name_suggestion) 7859edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko << CorrectedII->getName() 7869edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko << FixItHint::CreateReplacement(ArgRange, CorrectedII->getName()); 7879edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko } 7889edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko } 7899edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko} 7909edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7918487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenkobool Sema::isFunctionDecl() { 7921ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko if (!ThisDeclInfo) 7931ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko return false; 7941ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko if (!ThisDeclInfo->IsFilled) 79500c59f7ed2814f67d6d7e844479ea99eca9e55efDmitri Gribenko inspectThisDecl(); 796af19a6aaa2959ef5e76f19d51e87ef523bdeeddeDmitri Gribenko return ThisDeclInfo->getKind() == DeclInfo::FunctionKind; 7978487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko} 79899a7057098c56211e641705e1ff38d4b7c8b309dFariborz Jahanian 799eb8f69f094e95d0132e4a6817a2111ad188ab087Fariborz Jahanianbool Sema::isAnyFunctionDecl() { 800eb8f69f094e95d0132e4a6817a2111ad188ab087Fariborz Jahanian return isFunctionDecl() && ThisDeclInfo->CurrentDecl && 801eb8f69f094e95d0132e4a6817a2111ad188ab087Fariborz Jahanian isa<FunctionDecl>(ThisDeclInfo->CurrentDecl); 802eb8f69f094e95d0132e4a6817a2111ad188ab087Fariborz Jahanian} 803c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko 804c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenkobool Sema::isFunctionOrMethodVariadic() { 805c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko if (!isAnyFunctionDecl() && !isObjCMethodDecl()) 806c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko return false; 807c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko if (const FunctionDecl *FD = 808c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko dyn_cast<FunctionDecl>(ThisDeclInfo->CurrentDecl)) 809c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko return FD->isVariadic(); 810c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko if (const ObjCMethodDecl *MD = 811c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko dyn_cast<ObjCMethodDecl>(ThisDeclInfo->CurrentDecl)) 812c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko return MD->isVariadic(); 813c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko return false; 814c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko} 815c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko 81699a7057098c56211e641705e1ff38d4b7c8b309dFariborz Jahanianbool Sema::isObjCMethodDecl() { 81799a7057098c56211e641705e1ff38d4b7c8b309dFariborz Jahanian return isFunctionDecl() && ThisDeclInfo->CurrentDecl && 81899a7057098c56211e641705e1ff38d4b7c8b309dFariborz Jahanian isa<ObjCMethodDecl>(ThisDeclInfo->CurrentDecl); 81999a7057098c56211e641705e1ff38d4b7c8b309dFariborz Jahanian} 820a558d2e29817e36798875c96efb62251e53ff024Dmitri Gribenko 82199a7057098c56211e641705e1ff38d4b7c8b309dFariborz Jahanianbool Sema::isFunctionPointerVarDecl() { 822bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian if (!ThisDeclInfo) 823bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian return false; 824bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian if (!ThisDeclInfo->IsFilled) 825bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian inspectThisDecl(); 826bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian if (ThisDeclInfo->getKind() == DeclInfo::VariableKind) { 827bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian if (const VarDecl *VD = dyn_cast_or_null<VarDecl>(ThisDeclInfo->CurrentDecl)) { 828bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian QualType QT = VD->getType(); 829bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian return QT->isFunctionPointerType(); 830bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian } 831bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian } 832bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian return false; 833bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian} 834bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian 835664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanianbool Sema::isObjCPropertyDecl() { 836664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanian if (!ThisDeclInfo) 837664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanian return false; 838664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanian if (!ThisDeclInfo->IsFilled) 839664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanian inspectThisDecl(); 840664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanian return ThisDeclInfo->CurrentDecl->getKind() == Decl::ObjCProperty; 841664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanian} 8428487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko 84304bf29eb1b197e0a103139ab5d63b0b97432f004Dmitri Gribenkobool Sema::isTemplateOrSpecialization() { 8441ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko if (!ThisDeclInfo) 8451ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko return false; 8461ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko if (!ThisDeclInfo->IsFilled) 84796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko inspectThisDecl(); 84804bf29eb1b197e0a103139ab5d63b0b97432f004Dmitri Gribenko return ThisDeclInfo->getTemplateKind() != DeclInfo::NotTemplate; 84996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} 85096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 851b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanianbool Sema::isRecordLikeDecl() { 85228c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo) 85328c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return false; 85428c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo->IsFilled) 85528c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian inspectThisDecl(); 856b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian return isUnionDecl() || isClassOrStructDecl() 85728c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian || isObjCInterfaceDecl() || isObjCProtocolDecl(); 85828c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian} 85928c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian 86028c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanianbool Sema::isUnionDecl() { 86128c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo) 86228c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return false; 86328c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo->IsFilled) 86428c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian inspectThisDecl(); 86528c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (const RecordDecl *RD = 86628c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian dyn_cast_or_null<RecordDecl>(ThisDeclInfo->CurrentDecl)) 86728c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return RD->isUnion(); 86828c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return false; 86928c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian} 87028c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian 871b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanianbool Sema::isClassOrStructDecl() { 87228c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo) 87328c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return false; 87428c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo->IsFilled) 87528c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian inspectThisDecl(); 87628c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return ThisDeclInfo->CurrentDecl && 87728c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian isa<RecordDecl>(ThisDeclInfo->CurrentDecl) && 87828c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian !isUnionDecl(); 87928c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian} 8802d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian 8812d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanianbool Sema::isClassTemplateDecl() { 8822d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian if (!ThisDeclInfo) 8832d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian return false; 8842d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian if (!ThisDeclInfo->IsFilled) 8852d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian inspectThisDecl(); 8862d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian return ThisDeclInfo->CurrentDecl && 8872d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian (isa<ClassTemplateDecl>(ThisDeclInfo->CurrentDecl)); 8882d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian} 8892d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian 8902d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanianbool Sema::isFunctionTemplateDecl() { 8912d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian if (!ThisDeclInfo) 8922d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian return false; 8932d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian if (!ThisDeclInfo->IsFilled) 8942d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian inspectThisDecl(); 8952d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian return ThisDeclInfo->CurrentDecl && 8962d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian (isa<FunctionTemplateDecl>(ThisDeclInfo->CurrentDecl)); 8972d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian} 89828c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian 89928c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanianbool Sema::isObjCInterfaceDecl() { 90028c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo) 90128c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return false; 90228c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo->IsFilled) 90328c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian inspectThisDecl(); 90428c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return ThisDeclInfo->CurrentDecl && 90528c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian isa<ObjCInterfaceDecl>(ThisDeclInfo->CurrentDecl); 90628c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian} 90728c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian 90828c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanianbool Sema::isObjCProtocolDecl() { 90928c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo) 91028c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return false; 91128c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo->IsFilled) 91228c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian inspectThisDecl(); 91328c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return ThisDeclInfo->CurrentDecl && 91428c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian isa<ObjCProtocolDecl>(ThisDeclInfo->CurrentDecl); 91528c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian} 91628c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian 9178487c524fdfcea3da858fd0af850b4784c8096d0Dmitri GribenkoArrayRef<const ParmVarDecl *> Sema::getParamVars() { 9181ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko if (!ThisDeclInfo->IsFilled) 91900c59f7ed2814f67d6d7e844479ea99eca9e55efDmitri Gribenko inspectThisDecl(); 9201ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko return ThisDeclInfo->ParamVars; 9218487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko} 9228487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko 9238487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenkovoid Sema::inspectThisDecl() { 9241ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko ThisDeclInfo->fill(); 9258487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko} 9268487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko 927a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenkounsigned Sema::resolveParmVarReference(StringRef Name, 9288487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko ArrayRef<const ParmVarDecl *> ParamVars) { 9298487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko for (unsigned i = 0, e = ParamVars.size(); i != e; ++i) { 930a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko const IdentifierInfo *II = ParamVars[i]->getIdentifier(); 931a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (II && II->getName() == Name) 932a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko return i; 933a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 934c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko if (Name == "..." && isFunctionOrMethodVariadic()) 935c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko return ParamCommandComment::VarArgParamIndex; 936a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko return ParamCommandComment::InvalidParamIndex; 937a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko} 938a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 93996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkonamespace { 94096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkoclass SimpleTypoCorrector { 94196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko StringRef Typo; 94296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const unsigned MaxEditDistance; 94396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 94496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const NamedDecl *BestDecl; 94596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko unsigned BestEditDistance; 94696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko unsigned BestIndex; 94796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko unsigned NextIndex; 94896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 94996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkopublic: 95096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko SimpleTypoCorrector(StringRef Typo) : 95196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Typo(Typo), MaxEditDistance((Typo.size() + 2) / 3), 95296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko BestDecl(NULL), BestEditDistance(MaxEditDistance + 1), 95396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko BestIndex(0), NextIndex(0) 95496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko { } 95596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 95696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko void addDecl(const NamedDecl *ND); 95796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 95896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const NamedDecl *getBestDecl() const { 95996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (BestEditDistance > MaxEditDistance) 96096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return NULL; 96196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 96296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return BestDecl; 96396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 96496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 96596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko unsigned getBestDeclIndex() const { 96696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko assert(getBestDecl()); 96796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return BestIndex; 96896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 96996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko}; 97096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 97196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkovoid SimpleTypoCorrector::addDecl(const NamedDecl *ND) { 97296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko unsigned CurrIndex = NextIndex++; 97396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 97496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const IdentifierInfo *II = ND->getIdentifier(); 97596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (!II) 97696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return; 97796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 97896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko StringRef Name = II->getName(); 97996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko unsigned MinPossibleEditDistance = abs((int)Name.size() - (int)Typo.size()); 98096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (MinPossibleEditDistance > 0 && 98196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Typo.size() / MinPossibleEditDistance < 3) 98296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return; 98396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 98496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko unsigned EditDistance = Typo.edit_distance(Name, true, MaxEditDistance); 98596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (EditDistance < BestEditDistance) { 98696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko BestEditDistance = EditDistance; 98796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko BestDecl = ND; 98896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko BestIndex = CurrIndex; 98996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 99096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} 99196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} // unnamed namespace 99296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 993a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenkounsigned Sema::correctTypoInParmVarReference( 994a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko StringRef Typo, 9958487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko ArrayRef<const ParmVarDecl *> ParamVars) { 99696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko SimpleTypoCorrector Corrector(Typo); 99796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko for (unsigned i = 0, e = ParamVars.size(); i != e; ++i) 99896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Corrector.addDecl(ParamVars[i]); 99996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (Corrector.getBestDecl()) 100096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return Corrector.getBestDeclIndex(); 100196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko else 10021ad23d62007162df82b58bca31b4aa277a5f6586Dmitri Gribenko return ParamCommandComment::InvalidParamIndex; 100396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} 100496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 100596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkonamespace { 100696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkobool ResolveTParamReferenceHelper( 100796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko StringRef Name, 100896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const TemplateParameterList *TemplateParameters, 100996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko SmallVectorImpl<unsigned> *Position) { 101096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko for (unsigned i = 0, e = TemplateParameters->size(); i != e; ++i) { 101196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const NamedDecl *Param = TemplateParameters->getParam(i); 101296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const IdentifierInfo *II = Param->getIdentifier(); 101396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (II && II->getName() == Name) { 101496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Position->push_back(i); 101596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return true; 101696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 101796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 101896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (const TemplateTemplateParmDecl *TTP = 101996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko dyn_cast<TemplateTemplateParmDecl>(Param)) { 102096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Position->push_back(i); 102196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (ResolveTParamReferenceHelper(Name, TTP->getTemplateParameters(), 102296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Position)) 102396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return true; 102496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Position->pop_back(); 1025a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 1026a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 102796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return false; 102896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} 102996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} // unnamed namespace 1030a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 103196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkobool Sema::resolveTParamReference( 103296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko StringRef Name, 103396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const TemplateParameterList *TemplateParameters, 103496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko SmallVectorImpl<unsigned> *Position) { 103596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Position->clear(); 103696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (!TemplateParameters) 103796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return false; 103896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 103996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return ResolveTParamReferenceHelper(Name, TemplateParameters, Position); 104096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} 104196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 104296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkonamespace { 104396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkovoid CorrectTypoInTParamReferenceHelper( 104496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const TemplateParameterList *TemplateParameters, 104596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko SimpleTypoCorrector &Corrector) { 104696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko for (unsigned i = 0, e = TemplateParameters->size(); i != e; ++i) { 104796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const NamedDecl *Param = TemplateParameters->getParam(i); 104896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Corrector.addDecl(Param); 104996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 105096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (const TemplateTemplateParmDecl *TTP = 105196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko dyn_cast<TemplateTemplateParmDecl>(Param)) 105296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko CorrectTypoInTParamReferenceHelper(TTP->getTemplateParameters(), 105396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Corrector); 105496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 105596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} 105696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} // unnamed namespace 105796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 105896b098674908eaa59a9128f3305cda6fbbdad563Dmitri GribenkoStringRef Sema::correctTypoInTParamReference( 105996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko StringRef Typo, 106096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const TemplateParameterList *TemplateParameters) { 106196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko SimpleTypoCorrector Corrector(Typo); 106296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko CorrectTypoInTParamReferenceHelper(TemplateParameters, Corrector); 106396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (const NamedDecl *ND = Corrector.getBestDecl()) { 106496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const IdentifierInfo *II = ND->getIdentifier(); 106596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko assert(II && "SimpleTypoCorrector should not return this decl"); 106696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return II->getName(); 106796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 106896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return StringRef(); 1069a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko} 1070a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 10712d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri GribenkoInlineCommandComment::RenderKind 10722d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri GribenkoSema::getInlineCommandRenderKind(StringRef Name) const { 1073e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko assert(Traits.getCommandInfo(Name)->IsInlineCommand); 10742d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko 10752d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko return llvm::StringSwitch<InlineCommandComment::RenderKind>(Name) 10762d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko .Case("b", InlineCommandComment::RenderBold) 10772d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko .Cases("c", "p", InlineCommandComment::RenderMonospaced) 10782d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko .Cases("a", "e", "em", InlineCommandComment::RenderEmphasized) 10792d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko .Default(InlineCommandComment::RenderNormal); 10802d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko} 10812d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko 10828d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} // end namespace comments 10838d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} // end namespace clang 10848d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 1085