[cfe-commits] r125977 - in /cfe/trunk: include/clang/Basic/IdentifierTable.h lib/AST/DeclarationName.cpp lib/AST/StmtPrinter.cpp lib/Basic/IdentifierTable.cpp lib/Sema/SemaCodeComplete.cpp lib/Sema/SemaExpr.cpp test/Index/complete-method-decls.m test/SemaObjC/self-assign.m
Douglas Gregor
dgregor at apple.com
Fri Feb 18 14:29:55 PST 2011
Author: dgregor
Date: Fri Feb 18 16:29:55 2011
New Revision: 125977
URL: http://llvm.org/viewvc/llvm-project?rev=125977&view=rev
Log:
Selector::getIdentifierInfoForSlot() can return NULL values, a fact
that was ignored in a few places (most notably, code
completion). Introduce Selector::getNameForSlot() for the common case
where we only care about the name. Audit all uses of
getIdentifierInfoForSlot(), switching many over to getNameForSlot(),
fixing a few crashers.
Fixed <rdar://problem/8939352>, a code-completion crasher.
Added:
cfe/trunk/test/SemaObjC/self-assign.m
Modified:
cfe/trunk/include/clang/Basic/IdentifierTable.h
cfe/trunk/lib/AST/DeclarationName.cpp
cfe/trunk/lib/AST/StmtPrinter.cpp
cfe/trunk/lib/Basic/IdentifierTable.cpp
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/Index/complete-method-decls.m
Modified: cfe/trunk/include/clang/Basic/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/IdentifierTable.h?rev=125977&r1=125976&r2=125977&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/IdentifierTable.h (original)
+++ cfe/trunk/include/clang/Basic/IdentifierTable.h Fri Feb 18 16:29:55 2011
@@ -510,8 +510,33 @@
return getIdentifierInfoFlag() == ZeroArg;
}
unsigned getNumArgs() const;
+
+
+ /// \brief Retrieve the identifier at a given position in the selector.
+ ///
+ /// Note that the identifier pointer returned may be NULL. Clients that only
+ /// care about the text of the identifier string, and not the specific,
+ /// uniqued identifier pointer, should use \c getNameForSlot(), which returns
+ /// an empty string when the identifier pointer would be NULL.
+ ///
+ /// \param argIndex The index for which we want to retrieve the identifier.
+ /// This index shall be less than \c getNumArgs() unless this is a keyword
+ /// selector, in which case 0 is the only permissible value.
+ ///
+ /// \returns the uniqued identifier for this slot, or NULL if this slot has
+ /// no corresponding identifier.
IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const;
-
+
+ /// \brief Retrieve the name at a given position in the selector.
+ ///
+ /// \param argIndex The index for which we want to retrieve the name.
+ /// This index shall be less than \c getNumArgs() unless this is a keyword
+ /// selector, in which case 0 is the only permissible value.
+ ///
+ /// \returns the name for this slot, which may be the empty string if no
+ /// name was supplied.
+ llvm::StringRef getNameForSlot(unsigned argIndex) const;
+
/// getAsString - Derive the full selector name (e.g. "foo:bar:") and return
/// it as an std::string.
std::string getAsString() const;
Modified: cfe/trunk/lib/AST/DeclarationName.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclarationName.cpp?rev=125977&r1=125976&r2=125977&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclarationName.cpp (original)
+++ cfe/trunk/lib/AST/DeclarationName.cpp Fri Feb 18 16:29:55 2011
@@ -94,10 +94,8 @@
Selector RHSSelector = RHS.getObjCSelector();
unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
- IdentifierInfo *LHSId = LHSSelector.getIdentifierInfoForSlot(I);
- IdentifierInfo *RHSId = RHSSelector.getIdentifierInfoForSlot(I);
-
- switch (LHSId->getName().compare(RHSId->getName())) {
+ switch (LHSSelector.getNameForSlot(I).compare(
+ RHSSelector.getNameForSlot(I))) {
case -1: return true;
case 1: return false;
default: break;
Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=125977&r1=125976&r2=125977&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Fri Feb 18 16:29:55 2011
@@ -1311,7 +1311,7 @@
OS << ' ';
Selector selector = Mess->getSelector();
if (selector.isUnarySelector()) {
- OS << selector.getIdentifierInfoForSlot(0)->getName();
+ OS << selector.getNameForSlot(0);
} else {
for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
if (i < selector.getNumArgs()) {
Modified: cfe/trunk/lib/Basic/IdentifierTable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/IdentifierTable.cpp?rev=125977&r1=125976&r2=125977&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/IdentifierTable.cpp (original)
+++ cfe/trunk/lib/Basic/IdentifierTable.cpp Fri Feb 18 16:29:55 2011
@@ -326,6 +326,11 @@
return SI->getIdentifierInfoForSlot(argIndex);
}
+llvm::StringRef Selector::getNameForSlot(unsigned int argIndex) const {
+ IdentifierInfo *II = getIdentifierInfoForSlot(argIndex);
+ return II? II->getName() : llvm::StringRef();
+}
+
std::string MultiKeywordSelector::getName() const {
llvm::SmallString<256> Str;
llvm::raw_svector_ostream OS(Str);
Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=125977&r1=125976&r2=125977&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Fri Feb 18 16:29:55 2011
@@ -2391,11 +2391,11 @@
Selector Sel = Method->getSelector();
if (Sel.isUnarySelector()) {
Result.AddTypedTextChunk(Result.getAllocator().CopyString(
- Sel.getIdentifierInfoForSlot(0)->getName()));
+ Sel.getNameForSlot(0)));
return Result.TakeString();
}
- std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
+ std::string SelName = Sel.getNameForSlot(0).str();
SelName += ':';
if (StartParameter == 0)
Result.AddTypedTextChunk(Result.getAllocator().CopyString(SelName));
@@ -4531,10 +4531,10 @@
if (Sel.isUnarySelector()) {
if (NeedSuperKeyword)
Builder.AddTextChunk(Builder.getAllocator().CopyString(
- Sel.getIdentifierInfoForSlot(0)->getName()));
+ Sel.getNameForSlot(0)));
else
Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
- Sel.getIdentifierInfoForSlot(0)->getName()));
+ Sel.getNameForSlot(0)));
} else {
ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
@@ -4544,17 +4544,17 @@
if (I < NumSelIdents)
Builder.AddInformativeChunk(
Builder.getAllocator().CopyString(
- Sel.getIdentifierInfoForSlot(I)->getName().str() + ":"));
+ Sel.getNameForSlot(I) + ":"));
else if (NeedSuperKeyword || I > NumSelIdents) {
Builder.AddTextChunk(
Builder.getAllocator().CopyString(
- Sel.getIdentifierInfoForSlot(I)->getName().str() + ":"));
+ Sel.getNameForSlot(I) + ":"));
Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString(
(*CurP)->getIdentifier()->getName()));
} else {
Builder.AddTypedTextChunk(
Builder.getAllocator().CopyString(
- Sel.getIdentifierInfoForSlot(I)->getName().str() + ":"));
+ Sel.getNameForSlot(I) + ":"));
Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString(
(*CurP)->getIdentifier()->getName()));
}
@@ -5002,7 +5002,7 @@
CodeCompletionBuilder Builder(Results.getAllocator());
if (Sel.isUnarySelector()) {
Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
- Sel.getIdentifierInfoForSlot(0)->getName()));
+ Sel.getNameForSlot(0)));
Results.AddResult(Builder.TakeString());
continue;
}
@@ -5017,7 +5017,7 @@
}
}
- Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
+ Accumulator += Sel.getNameForSlot(I).str();
Accumulator += ':';
}
Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( Accumulator));
@@ -6115,7 +6115,7 @@
// Add the first part of the selector to the pattern.
Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(
- Sel.getIdentifierInfoForSlot(0)->getName()));
+ Sel.getNameForSlot(0)));
// Add parameters to the pattern.
unsigned I = 0;
@@ -6128,9 +6128,7 @@
else if (I < Sel.getNumArgs()) {
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
Builder.AddTypedTextChunk(
- Builder.getAllocator().CopyString(
- (Sel.getIdentifierInfoForSlot(I)->getName()
- + ":").str()));
+ Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":"));
} else
break;
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=125977&r1=125976&r2=125977&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Feb 18 16:29:55 2011
@@ -9487,13 +9487,11 @@
Selector Sel = ME->getSelector();
// self = [<foo> init...]
- if (isSelfExpr(Op->getLHS())
- && Sel.getIdentifierInfoForSlot(0)->getName().startswith("init"))
+ if (isSelfExpr(Op->getLHS()) && Sel.getNameForSlot(0).startswith("init"))
diagnostic = diag::warn_condition_is_idiomatic_assignment;
// <foo> = [<bar> nextObject]
- else if (Sel.isUnarySelector() &&
- Sel.getIdentifierInfoForSlot(0)->getName() == "nextObject")
+ else if (Sel.isUnarySelector() && Sel.getNameForSlot(0) == "nextObject")
diagnostic = diag::warn_condition_is_idiomatic_assignment;
}
Modified: cfe/trunk/test/Index/complete-method-decls.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-method-decls.m?rev=125977&r1=125976&r2=125977&view=diff
==============================================================================
--- cfe/trunk/test/Index/complete-method-decls.m (original)
+++ cfe/trunk/test/Index/complete-method-decls.m Fri Feb 18 16:29:55 2011
@@ -60,6 +60,14 @@
- (oneway void)method:(in id x);
@end
+ at interface Gaps
+- (void)method:(int)x :(int)y;
+ at end
+
+ at implementation Gaps
+- (void)method:(int)x :(int)y;
+ at end
+
// RUN: c-index-test -code-completion-at=%s:17:3 %s | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText abc}
// CHECK-CC1: ObjCInstanceMethodDecl:{LeftParen (}{Text int}{RightParen )}{TypedText getInt}
@@ -163,3 +171,6 @@
// RUN: c-index-test -code-completion-at=%s:5:4 %s | FileCheck -check-prefix=CHECK-IBACTION %s
// CHECK-IBACTION: NotImplemented:{TypedText IBAction}{RightParen )}{Placeholder selector}{Colon :}{LeftParen (}{Text id}{RightParen )}{Text sender} (40)
+// <rdar://problem/8939352>
+// RUN: c-index-test -code-completion-at=%s:68:9 %s | FileCheck -check-prefix=CHECK-8939352 %s
+// CHECK-8939352: ObjCInstanceMethodDecl:{TypedText method}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace }{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text y} (40)
Added: cfe/trunk/test/SemaObjC/self-assign.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/self-assign.m?rev=125977&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/self-assign.m (added)
+++ cfe/trunk/test/SemaObjC/self-assign.m Fri Feb 18 16:29:55 2011
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+ at interface A
+ at end
+
+ at implementation A
+- (id):(int)x :(int)y {
+ int z;
+ // <rdar://problem/8939352>
+ if (self = [self :x :y]) {} // expected-warning{{using the result of an assignment as a condition without parentheses}} \
+ // expected-note{{use '==' to turn this assignment into an equality comparison}} \
+ // expected-note{{place parentheses around the assignment to silence this warning}}
+ return self;
+}
+ at end
More information about the cfe-commits
mailing list