]> granicus.if.org Git - clang/commitdiff
[AST][ObjC] Print implicit property expression that only has a setter without crashing
authorAlex Lorenz <arphaman@gmail.com>
Wed, 23 May 2018 00:52:20 +0000 (00:52 +0000)
committerAlex Lorenz <arphaman@gmail.com>
Wed, 23 May 2018 00:52:20 +0000 (00:52 +0000)
rdar://40447209

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@333046 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/IdentifierTable.h
lib/AST/StmtPrinter.cpp
lib/Basic/IdentifierTable.cpp
test/Misc/ast-print-objectivec.m

index 10a0251453721a2422c8da3d6f215741fd8d8152..9a33873518126914e9bf3fc18761a531e26a5fd9 100644 (file)
@@ -825,6 +825,9 @@ public:
   static Selector constructSetterSelector(IdentifierTable &Idents,
                                           SelectorTable &SelTable,
                                           const IdentifierInfo *Name);
+
+  /// Return the property name for the given setter selector.
+  static std::string getPropertyNameFromSetterSelector(Selector Sel);
 };
 
 /// DeclarationNameExtra - Common base of the MultiKeywordSelector,
index dc6cc1607150f2a4f9cc73119a8687ae72ffe5ba..38ec6632e78e41e1acfe29e2ffb421812c0f9543 100644 (file)
@@ -1406,9 +1406,13 @@ void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
     OS << Node->getClassReceiver()->getName() << ".";
   }
 
-  if (Node->isImplicitProperty())
-    Node->getImplicitPropertyGetter()->getSelector().print(OS);
-  else
+  if (Node->isImplicitProperty()) {
+    if (const auto *Getter = Node->getImplicitPropertyGetter())
+      Getter->getSelector().print(OS);
+    else
+      OS << SelectorTable::getPropertyNameFromSetterSelector(
+          Node->getImplicitPropertySetter()->getSelector());
+  } else
     OS << Node->getExplicitProperty()->getName();
 }
 
index ec9ca7616cbb41644540a85d5e3c9956db630a88..37703ca776d0bb6e4284bff41f7b6956937c5607 100644 (file)
@@ -645,6 +645,12 @@ SelectorTable::constructSetterSelector(IdentifierTable &Idents,
   return SelTable.getUnarySelector(SetterName);
 }
 
+std::string SelectorTable::getPropertyNameFromSetterSelector(Selector Sel) {
+  StringRef Name = Sel.getNameForSlot(0);
+  assert(Name.startswith("set") && "invalid setter name");
+  return (Twine(toLowercase(Name[3])) + Name.drop_front(4)).str();
+}
+
 size_t SelectorTable::getTotalMemory() const {
   SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl);
   return SelTabImpl.Allocator.getTotalMemory();
index eb1b4696105396e15a6f772f23b9e5d0f3aec72e..05a0a5d4aa74c47fb7592dd0b08b6d796733d8ae 100644 (file)
@@ -50,3 +50,13 @@ struct __attribute__((objc_bridge_related(C1,,))) S1;
 
 // CHECK: @class C1;
 // CHECK: struct __attribute__((objc_bridge_related(C1, , ))) S1;
+
+@interface ImplicitPropertyWithSetterOnly
+
+- (void)setX:(int)x;
+
+@end
+
+void printImplicitPropertyWithSetterOnly(ImplicitPropertyWithSetterOnly *x) {
+  x.x = 313; // CHECK: x.x = 313;
+}