diff options
author | Dmitri Gribenko <gribozavr@gmail.com> | 2012-07-23 17:40:30 +0000 |
---|---|---|
committer | Dmitri Gribenko <gribozavr@gmail.com> | 2012-07-23 17:40:30 +0000 |
commit | 8487c524fdfcea3da858fd0af850b4784c8096d0 (patch) | |
tree | 7bc0c39e71d92389e7ca732f3fc03c004fa68a46 | |
parent | 2d66a5016d4aacce362f89290261c8a1a6eef0d3 (diff) |
Comment Sema: refactor handling of 'ParmVarDecl's and save them in Sema members.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160634 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/CommentSema.h | 27 | ||||
-rw-r--r-- | lib/AST/CommentSema.cpp | 75 |
2 files changed, 72 insertions, 30 deletions
diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h index be8179d126..f8b35d0c6f 100644 --- a/include/clang/AST/CommentSema.h +++ b/include/clang/AST/CommentSema.h @@ -38,8 +38,22 @@ class Sema { DiagnosticsEngine &Diags; + /// Declaration this comment is attached to. const Decl *ThisDecl; + /// Parameters that can be referenced by \\param if \c ThisDecl is something + /// that we consider a "function". + /// Contains a valid value if \c IsThisDeclInspected is true. + ArrayRef<const ParmVarDecl *> ParamVars; + + /// True if we extracted all important information from \c ThisDecl into + /// \c Sema members. + unsigned IsThisDeclInspected : 1; + + /// Is \c ThisDecl something that we consider a "function". + /// Contains a valid value if \c IsThisDeclInspected is true. + unsigned IsFunctionDecl : 1; + DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) { return Diags.Report(Loc, DiagID); } @@ -140,16 +154,21 @@ public: void checkBlockCommandEmptyParagraph(BlockCommandComment *Command); + bool isFunctionDecl(); + ArrayRef<const ParmVarDecl *> getParamVars(); + + /// Extract all important semantic information from \c ThisDecl into + /// \c Sema members. + void inspectThisDecl(); + /// Returns index of a function parameter with a given name. unsigned resolveParmVarReference(StringRef Name, - const ParmVarDecl * const *ParamVars, - unsigned NumParams); + ArrayRef<const ParmVarDecl *> ParamVars); /// Returns index of a function parameter with the name closest to a given /// typo. unsigned correctTypoInParmVarReference(StringRef Typo, - const ParmVarDecl * const *ParamVars, - unsigned NumParams); + ArrayRef<const ParmVarDecl *> ParamVars); bool isBlockCommand(StringRef Name); bool isParamCommand(StringRef Name); diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp index 6c37452e07..bfc9b91b0a 100644 --- a/lib/AST/CommentSema.cpp +++ b/lib/AST/CommentSema.cpp @@ -19,7 +19,8 @@ namespace comments { Sema::Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr, DiagnosticsEngine &Diags) : - Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags), ThisDecl(NULL) { + Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags), ThisDecl(NULL), + IsThisDeclInspected(false) { } void Sema::setDecl(const Decl *D) { @@ -58,8 +59,7 @@ ParamCommandComment *Sema::actOnParamCommandStart(SourceLocation LocBegin, ParamCommandComment *Command = new (Allocator) ParamCommandComment(LocBegin, LocEnd, Name); - if (!ThisDecl || - !(isa<FunctionDecl>(ThisDecl) || isa<ObjCMethodDecl>(ThisDecl))) + if (!isFunctionDecl()) Diag(Command->getLocation(), diag::warn_doc_param_not_attached_to_a_function_decl) << Command->getCommandNameRange(); @@ -142,25 +142,15 @@ ParamCommandComment *Sema::actOnParamCommandParamNameArg( Arg); Command->setArgs(llvm::makeArrayRef(A, 1)); - if (!ThisDecl) - return Command; - - const ParmVarDecl * const *ParamVars; - unsigned NumParams; - if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ThisDecl)) { - ParamVars = FD->param_begin(); - NumParams = FD->getNumParams(); - } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(ThisDecl)) { - ParamVars = MD->param_begin(); - NumParams = MD->param_size(); - } else { + if (!isFunctionDecl()) { // We already warned that this \\param is not attached to a function decl. return Command; } + ArrayRef<const ParmVarDecl *> ParamVars = getParamVars(); + // Check that referenced parameter name is in the function decl. - const unsigned ResolvedParamIndex = resolveParmVarReference(Arg, ParamVars, - NumParams); + const unsigned ResolvedParamIndex = resolveParmVarReference(Arg, ParamVars); if (ResolvedParamIndex != ParamCommandComment::InvalidParamIndex) { Command->setParamIndex(ResolvedParamIndex); return Command; @@ -171,14 +161,13 @@ ParamCommandComment *Sema::actOnParamCommandParamNameArg( << Arg << ArgRange; unsigned CorrectedParamIndex = ParamCommandComment::InvalidParamIndex; - if (NumParams == 1) { + if (ParamVars.size() == 1) { // If function has only one parameter then only that parameter // can be documented. CorrectedParamIndex = 0; } else { // Do typo correction. - CorrectedParamIndex = correctTypoInParmVarReference(Arg, ParamVars, - NumParams); + CorrectedParamIndex = correctTypoInParmVarReference(Arg, ParamVars); } if (CorrectedParamIndex != ParamCommandComment::InvalidParamIndex) { const ParmVarDecl *CorrectedPVD = ParamVars[CorrectedParamIndex]; @@ -362,6 +351,7 @@ HTMLEndTagComment *Sema::actOnHTMLEndTag(SourceLocation LocBegin, FullComment *Sema::actOnFullComment( ArrayRef<BlockContentComment *> Blocks) { + SmallVector<ParamCommandComment *, 8> Params; return new (Allocator) FullComment(Blocks); } @@ -379,10 +369,44 @@ void Sema::checkBlockCommandEmptyParagraph(BlockCommandComment *Command) { } } +bool Sema::isFunctionDecl() { + if (IsThisDeclInspected) + return IsFunctionDecl; + + inspectThisDecl(); + return IsFunctionDecl; +} + +ArrayRef<const ParmVarDecl *> Sema::getParamVars() { + if (IsThisDeclInspected) + return ParamVars; + + inspectThisDecl(); + return ParamVars; +} + +void Sema::inspectThisDecl() { + if (!ThisDecl) { + IsFunctionDecl = false; + ParamVars = ArrayRef<const ParmVarDecl *>(); + } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ThisDecl)) { + IsFunctionDecl = true; + ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(), + FD->getNumParams()); + } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(ThisDecl)) { + IsFunctionDecl = true; + ParamVars = ArrayRef<const ParmVarDecl *>(MD->param_begin(), + MD->param_size()); + } else { + IsFunctionDecl = false; + ParamVars = ArrayRef<const ParmVarDecl *>(); + } + IsThisDeclInspected = true; +} + unsigned Sema::resolveParmVarReference(StringRef Name, - const ParmVarDecl * const *ParamVars, - unsigned NumParams) { - for (unsigned i = 0; i != NumParams; ++i) { + ArrayRef<const ParmVarDecl *> ParamVars) { + for (unsigned i = 0, e = ParamVars.size(); i != e; ++i) { const IdentifierInfo *II = ParamVars[i]->getIdentifier(); if (II && II->getName() == Name) return i; @@ -392,12 +416,11 @@ unsigned Sema::resolveParmVarReference(StringRef Name, unsigned Sema::correctTypoInParmVarReference( StringRef Typo, - const ParmVarDecl * const *ParamVars, - unsigned NumParams) { + ArrayRef<const ParmVarDecl *> ParamVars) { const unsigned MaxEditDistance = (Typo.size() + 2) / 3; unsigned BestPVDIndex = 0; unsigned BestEditDistance = MaxEditDistance + 1; - for (unsigned i = 0; i != NumParams; ++i) { + for (unsigned i = 0, e = ParamVars.size(); i != e; ++i) { const IdentifierInfo *II = ParamVars[i]->getIdentifier(); if (II) { StringRef Name = II->getName(); |