[cfe-commits] r162570 - in /cfe/trunk: include/clang/AST/CommentSema.h lib/AST/CommentSema.cpp test/Sema/warn-documentation.cpp test/Sema/warn-documentation.m
Dmitri Gribenko
gribozavr at gmail.com
Fri Aug 24 10:45:39 PDT 2012
Author: gribozavr
Date: Fri Aug 24 12:45:39 2012
New Revision: 162570
URL: http://llvm.org/viewvc/llvm-project?rev=162570&view=rev
Log:
Comment diagnostics: for unresolved parameters, do not suggest parameter fixit
with parameter that is documented.
Fixes PR13670, <rdar://problem/12155840>.
Modified:
cfe/trunk/include/clang/AST/CommentSema.h
cfe/trunk/lib/AST/CommentSema.cpp
cfe/trunk/test/Sema/warn-documentation.cpp
cfe/trunk/test/Sema/warn-documentation.m
Modified: cfe/trunk/include/clang/AST/CommentSema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CommentSema.h?rev=162570&r1=162569&r2=162570&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/CommentSema.h (original)
+++ cfe/trunk/include/clang/AST/CommentSema.h Fri Aug 24 12:45:39 2012
@@ -46,13 +46,6 @@
/// Information about the declaration this comment is attached to.
DeclInfo *ThisDeclInfo;
- /// Comment AST nodes that correspond to \c ParamVars for which we have
- /// found a \\param command or NULL if no documentation was found so far.
- ///
- /// Has correct size and contains valid values if \c DeclInfo->IsFilled is
- /// true.
- llvm::SmallVector<ParamCommandComment *, 8> ParamVarDocs;
-
/// Comment AST nodes that correspond to parameter names in
/// \c TemplateParameters.
///
@@ -190,6 +183,10 @@
/// used only once per comment, e.g., \\brief and \\returns.
void checkBlockCommandDuplicate(const BlockCommandComment *Command);
+ /// Resolve parameter names to parameter indexes in function declaration.
+ /// Emit diagnostics about unknown parametrs.
+ void resolveParamCommandIndexes(const FullComment *FC);
+
bool isFunctionDecl();
bool isTemplateOrSpecialization();
Modified: cfe/trunk/lib/AST/CommentSema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CommentSema.cpp?rev=162570&r1=162569&r2=162570&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CommentSema.cpp (original)
+++ cfe/trunk/lib/AST/CommentSema.cpp Fri Aug 24 12:45:39 2012
@@ -142,56 +142,6 @@
ArgLocEnd),
Arg);
Command->setArgs(llvm::makeArrayRef(A, 1));
-
- if (!isFunctionDecl()) {
- // We already warned that this \\param is not attached to a function decl.
- return;
- }
-
- ArrayRef<const ParmVarDecl *> ParamVars = getParamVars();
-
- // Check that referenced parameter name is in the function decl.
- const unsigned ResolvedParamIndex = resolveParmVarReference(Arg, ParamVars);
- if (ResolvedParamIndex != ParamCommandComment::InvalidParamIndex) {
- Command->setParamIndex(ResolvedParamIndex);
- if (ParamVarDocs[ResolvedParamIndex]) {
- SourceRange ArgRange(ArgLocBegin, ArgLocEnd);
- Diag(ArgLocBegin, diag::warn_doc_param_duplicate)
- << Arg << ArgRange;
- ParamCommandComment *PrevCommand = ParamVarDocs[ResolvedParamIndex];
- Diag(PrevCommand->getLocation(), diag::note_doc_param_previous)
- << PrevCommand->getParamNameRange();
- }
- ParamVarDocs[ResolvedParamIndex] = Command;
- return;
- }
-
- SourceRange ArgRange(ArgLocBegin, ArgLocEnd);
- Diag(ArgLocBegin, diag::warn_doc_param_not_found)
- << Arg << ArgRange;
-
- // No parameters -- can't suggest a correction.
- if (ParamVars.size() == 0)
- return;
-
- unsigned CorrectedParamIndex = ParamCommandComment::InvalidParamIndex;
- 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);
- }
- if (CorrectedParamIndex != ParamCommandComment::InvalidParamIndex) {
- const ParmVarDecl *CorrectedPVD = ParamVars[CorrectedParamIndex];
- if (const IdentifierInfo *CorrectedII = CorrectedPVD->getIdentifier())
- Diag(ArgLocBegin, diag::note_doc_param_name_suggestion)
- << CorrectedII->getName()
- << FixItHint::CreateReplacement(ArgRange, CorrectedII->getName());
- }
-
- return;
}
void Sema::actOnParamCommandFinish(ParamCommandComment *Command,
@@ -445,7 +395,9 @@
FullComment *Sema::actOnFullComment(
ArrayRef<BlockContentComment *> Blocks) {
- return new (Allocator) FullComment(Blocks, ThisDeclInfo);
+ FullComment *FC = new (Allocator) FullComment(Blocks, ThisDeclInfo);
+ resolveParamCommandIndexes(FC);
+ return FC;
}
void Sema::checkBlockCommandEmptyParagraph(BlockCommandComment *Command) {
@@ -529,6 +481,91 @@
<< Name;
}
+void Sema::resolveParamCommandIndexes(const FullComment *FC) {
+ if (!isFunctionDecl()) {
+ // We already warned that \\param commands are not attached to a function
+ // decl.
+ return;
+ }
+
+ llvm::SmallVector<ParamCommandComment *, 8> UnresolvedParamCommands;
+
+ // Comment AST nodes that correspond to \c ParamVars for which we have
+ // found a \\param command or NULL if no documentation was found so far.
+ llvm::SmallVector<ParamCommandComment *, 8> ParamVarDocs;
+
+ ArrayRef<const ParmVarDecl *> ParamVars = getParamVars();
+ ParamVarDocs.resize(ParamVars.size(), NULL);
+
+ // First pass over all \\param commands: resolve all parameter names.
+ for (Comment::child_iterator I = FC->child_begin(), E = FC->child_end();
+ I != E; ++I) {
+ ParamCommandComment *PCC = dyn_cast<ParamCommandComment>(*I);
+ if (!PCC || !PCC->hasParamName())
+ continue;
+ StringRef ParamName = PCC->getParamName();
+
+ // Check that referenced parameter name is in the function decl.
+ const unsigned ResolvedParamIndex = resolveParmVarReference(ParamName,
+ ParamVars);
+ if (ResolvedParamIndex == ParamCommandComment::InvalidParamIndex) {
+ UnresolvedParamCommands.push_back(PCC);
+ continue;
+ }
+ PCC->setParamIndex(ResolvedParamIndex);
+ if (ParamVarDocs[ResolvedParamIndex]) {
+ SourceRange ArgRange = PCC->getParamNameRange();
+ Diag(ArgRange.getBegin(), diag::warn_doc_param_duplicate)
+ << ParamName << ArgRange;
+ ParamCommandComment *PrevCommand = ParamVarDocs[ResolvedParamIndex];
+ Diag(PrevCommand->getLocation(), diag::note_doc_param_previous)
+ << PrevCommand->getParamNameRange();
+ }
+ ParamVarDocs[ResolvedParamIndex] = PCC;
+ }
+
+ // Find parameter declarations that have no corresponding \\param.
+ llvm::SmallVector<const ParmVarDecl *, 8> OrphanedParamDecls;
+ for (unsigned i = 0, e = ParamVarDocs.size(); i != e; ++i) {
+ if (!ParamVarDocs[i])
+ OrphanedParamDecls.push_back(ParamVars[i]);
+ }
+
+ // Second pass over unresolved \\param commands: do typo correction.
+ // Suggest corrections from a set of parameter declarations that have no
+ // corresponding \\param.
+ for (unsigned i = 0, e = UnresolvedParamCommands.size(); i != e; ++i) {
+ const ParamCommandComment *PCC = UnresolvedParamCommands[i];
+
+ SourceRange ArgRange = PCC->getParamNameRange();
+ StringRef ParamName = PCC->getParamName();
+ Diag(ArgRange.getBegin(), diag::warn_doc_param_not_found)
+ << ParamName << ArgRange;
+
+ // All parameters documented -- can't suggest a correction.
+ if (OrphanedParamDecls.size() == 0)
+ continue;
+
+ unsigned CorrectedParamIndex = ParamCommandComment::InvalidParamIndex;
+ if (OrphanedParamDecls.size() == 1) {
+ // If one parameter is not documented then that parameter is the only
+ // possible suggestion.
+ CorrectedParamIndex = 0;
+ } else {
+ // Do typo correction.
+ CorrectedParamIndex = correctTypoInParmVarReference(ParamName,
+ OrphanedParamDecls);
+ }
+ if (CorrectedParamIndex != ParamCommandComment::InvalidParamIndex) {
+ const ParmVarDecl *CorrectedPVD = OrphanedParamDecls[CorrectedParamIndex];
+ if (const IdentifierInfo *CorrectedII = CorrectedPVD->getIdentifier())
+ Diag(ArgRange.getBegin(), diag::note_doc_param_name_suggestion)
+ << CorrectedII->getName()
+ << FixItHint::CreateReplacement(ArgRange, CorrectedII->getName());
+ }
+ }
+}
+
bool Sema::isFunctionDecl() {
if (!ThisDeclInfo)
return false;
@@ -553,7 +590,6 @@
void Sema::inspectThisDecl() {
ThisDeclInfo->fill();
- ParamVarDocs.resize(ThisDeclInfo->ParamVars.size(), NULL);
}
unsigned Sema::resolveParmVarReference(StringRef Name,
Modified: cfe/trunk/test/Sema/warn-documentation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-documentation.cpp?rev=162570&r1=162569&r2=162570&view=diff
==============================================================================
--- cfe/trunk/test/Sema/warn-documentation.cpp (original)
+++ cfe/trunk/test/Sema/warn-documentation.cpp Fri Aug 24 12:45:39 2012
@@ -218,9 +218,32 @@
/// \param aab Blah blah.
int test_param13(int aaa, int bbb);
+// expected-warning at +2 {{parameter 'aab' not found in the function declaration}} expected-note at +2 {{did you mean 'bbb'?}}
+/// \param aaa Blah blah.
+/// \param aab Blah blah.
+int test_param14(int aaa, int bbb);
+
// expected-warning at +1 {{parameter 'aab' not found in the function declaration}}
/// \param aab Blah blah.
-int test_param14(int bbb, int ccc);
+int test_param15(int bbb, int ccc);
+
+// expected-warning at +1 {{parameter 'aab' not found in the function declaration}}
+/// \param aab Ccc.
+/// \param aaa Aaa.
+/// \param bbb Bbb.
+int test_param16(int aaa, int bbb);
+
+// expected-warning at +2 {{parameter 'aab' not found in the function declaration}}
+/// \param aaa Aaa.
+/// \param aab Ccc.
+/// \param bbb Bbb.
+int test_param17(int aaa, int bbb);
+
+// expected-warning at +3 {{parameter 'aab' not found in the function declaration}}
+/// \param aaa Aaa.
+/// \param bbb Bbb.
+/// \param aab Ccc.
+int test_param18(int aaa, int bbb);
class C {
// expected-warning at +1 {{parameter 'aaa' not found in the function declaration}}
@@ -229,50 +252,51 @@
// expected-warning at +1 {{parameter 'aaa' not found in the function declaration}}
/// \param aaa Blah blah.
- int test_param15(int bbb, int ccc);
+ int test_param19(int bbb, int ccc);
};
// expected-warning at +1 {{parameter 'aab' not found in the function declaration}}
/// \param aab Blah blah.
template<typename T>
-void test_param16(int bbb, int ccc);
+void test_param20(int bbb, int ccc);
// expected-warning at +3 {{parameter 'a' is already documented}}
// expected-note at +1 {{previous documentation}}
/// \param a Aaa.
/// \param a Aaa.
-int test_param17(int a);
+int test_param21(int a);
// expected-warning at +4 {{parameter 'x2' is already documented}}
// expected-note at +2 {{previous documentation}}
/// \param x1 Aaa.
/// \param x2 Bbb.
/// \param x2 Ccc.
-int test_param18(int x1, int x2, int x3);
+int test_param22(int x1, int x2, int x3);
-// expected-warning at +2 {{parameter 'bbb' not found in the function declaration}} expected-note at +2 {{did you mean 'aaa'?}}
+// expected-warning at +2 {{parameter 'bbb' not found in the function declaration}} expected-note at +2 {{did you mean 'ccc'?}}
/// \param aaa Meow.
/// \param bbb Bbb.
/// \returns aaa.
-typedef int test_param19(int aaa);
+typedef int test_param23(int aaa, int ccc);
-// expected-warning at +2 {{parameter 'bbb' not found in the function declaration}} expected-note at +2 {{did you mean 'aaa'?}}
+// expected-warning at +2 {{parameter 'bbb' not found in the function declaration}} expected-note at +2 {{did you mean 'ccc'?}}
/// \param aaa Meow.
/// \param bbb Bbb.
/// \returns aaa.
-typedef int (*test_param20)(int aaa);
+typedef int (*test_param24)(int aaa, int ccc);
-// expected-warning at +2 {{parameter 'bbb' not found in the function declaration}} expected-note at +2 {{did you mean 'aaa'?}}
+// expected-warning at +2 {{parameter 'bbb' not found in the function declaration}} expected-note at +2 {{did you mean 'ccc'?}}
/// \param aaa Meow.
/// \param bbb Bbb.
/// \returns aaa.
-typedef int (* const test_param21)(int aaa);
+typedef int (* const test_param25)(int aaa, int ccc);
-// expected-warning at +2 {{parameter 'bbb' not found in the function declaration}} expected-note at +2 {{did you mean 'aaa'?}}
+// expected-warning at +2 {{parameter 'bbb' not found in the function declaration}} expected-note at +2 {{did you mean 'ccc'?}}
/// \param aaa Meow.
/// \param bbb Bbb.
/// \returns aaa.
-typedef int (C::*test_param22)(int aaa);
+typedef int (C::*test_param26)(int aaa, int ccc);
+
// expected-warning at +1 {{'\tparam' command used in a comment that is not attached to a template declaration}}
/// \tparam T Aaa
Modified: cfe/trunk/test/Sema/warn-documentation.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-documentation.m?rev=162570&r1=162569&r2=162570&view=diff
==============================================================================
--- cfe/trunk/test/Sema/warn-documentation.m (original)
+++ cfe/trunk/test/Sema/warn-documentation.m Fri Aug 24 12:45:39 2012
@@ -91,9 +91,9 @@
- (void)test2:(NSString *)aaa;
@end
-// expected-warning at +2 {{parameter 'bbb' not found in the function declaration}} expected-note at +2 {{did you mean 'aaa'?}}
+// expected-warning at +2 {{parameter 'bbb' not found in the function declaration}} expected-note at +2 {{did you mean 'ccc'?}}
/// \param aaa Meow.
/// \param bbb Bbb.
/// \returns aaa.
-typedef int (^test_param1)(int aaa);
+typedef int (^test_param1)(int aaa, int ccc);
More information about the cfe-commits
mailing list