]> granicus.if.org Git - clang/commitdiff
For an Objective-C @synthesize statement, e.g.,
authorDouglas Gregor <dgregor@apple.com>
Wed, 17 Nov 2010 01:03:52 +0000 (01:03 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 17 Nov 2010 01:03:52 +0000 (01:03 +0000)
  @synthesize foo = _foo;

keep track of the location of the ivar ("_foo"). Teach libclang to
visit the ivar as a member reference.

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

include/clang/AST/DeclObjC.h
include/clang/Sema/Sema.h
lib/AST/DeclObjC.cpp
lib/Parse/ParseObjc.cpp
lib/Sema/SemaObjCProperty.cpp
lib/Serialization/ASTReaderDecl.cpp
lib/Serialization/ASTWriterDecl.cpp
test/Index/annotate-tokens.m
tools/libclang/CIndex.cpp

index e913f551a578316ebc3df53ae8a3921d459327d5..621fa9d4c08a454502deaf065249efe77fc2dfa4 100644 (file)
@@ -1455,6 +1455,15 @@ public:
   };
 private:
   SourceLocation AtLoc;   // location of @synthesize or @dynamic
+  
+  /// \brief For @synthesize, the location of the ivar, if it was written in
+  /// the source code.
+  ///
+  /// \code
+  /// @synthesize int a = b
+  /// \endcode
+  SourceLocation IvarLoc;
+  
   /// Property declaration being implemented
   ObjCPropertyDecl *PropertyDecl;
 
@@ -1471,9 +1480,10 @@ private:
   ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
                        ObjCPropertyDecl *property,
                        Kind PK,
-                       ObjCIvarDecl *ivarDecl)
+                       ObjCIvarDecl *ivarDecl,
+                       SourceLocation ivarLoc)
     : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
-      PropertyDecl(property), PropertyIvarDecl(ivarDecl),
+      IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl), 
       GetterCXXConstructor(0), SetterCXXAssignment(0) {
     assert (PK == Dynamic || PropertyIvarDecl);
   }
@@ -1483,11 +1493,11 @@ public:
                                       SourceLocation atLoc, SourceLocation L,
                                       ObjCPropertyDecl *property,
                                       Kind PK,
-                                      ObjCIvarDecl *ivarDecl);
+                                      ObjCIvarDecl *ivarDecl,
+                                      SourceLocation ivarLoc);
 
-  virtual SourceRange getSourceRange() const {
-    return SourceRange(AtLoc, getLocation());
-  }
+  virtual SourceRange getSourceRange() const;
+  
   SourceLocation getLocStart() const { return AtLoc; }
   void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
 
@@ -1503,7 +1513,13 @@ public:
   ObjCIvarDecl *getPropertyIvarDecl() const {
     return PropertyIvarDecl;
   }
-  void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { PropertyIvarDecl = Ivar; }
+  SourceLocation getPropertyIvarDeclLoc() const { return IvarLoc; }
+  
+  void setPropertyIvarDecl(ObjCIvarDecl *Ivar,
+                           SourceLocation IvarLoc) { 
+    PropertyIvarDecl = Ivar; 
+    this->IvarLoc = IvarLoc;
+  }
   
   Expr *getGetterCXXConstructor() const {
     return GetterCXXConstructor;
@@ -1522,6 +1538,8 @@ public:
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classof(const ObjCPropertyImplDecl *D) { return true; }
   static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
+  
+  friend class ASTDeclReader;
 };
 
 }  // end namespace clang
index 38b4f8b2ab9a6e2d49dabe4f484d520857b0af19..61e263065a9c2b1a8ba073d1269e533fecf23b26 100644 (file)
@@ -3781,7 +3781,8 @@ public:
                               SourceLocation PropertyLoc,
                               bool ImplKind,Decl *ClassImplDecl,
                               IdentifierInfo *PropertyId,
-                              IdentifierInfo *PropertyIvar);
+                              IdentifierInfo *PropertyIvar,
+                              SourceLocation PropertyIvarLoc);
 
   struct ObjCArgInfo {
     IdentifierInfo *Name;
index 817f7073af1318314b96d89cb483478a95315d84..5e57cf87b9ea1324b5a63010d135d5c5c3806b9d 100644 (file)
@@ -896,7 +896,6 @@ ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
   return new (C) ObjCPropertyDecl(DC, L, Id, AtLoc, T);
 }
 
-
 //===----------------------------------------------------------------------===//
 // ObjCPropertyImplDecl
 //===----------------------------------------------------------------------===//
@@ -907,8 +906,16 @@ ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
                                                    SourceLocation L,
                                                    ObjCPropertyDecl *property,
                                                    Kind PK,
-                                                   ObjCIvarDecl *ivar) {
-  return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
+                                                   ObjCIvarDecl *ivar,
+                                                   SourceLocation ivarLoc) {
+  return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
+                                      ivarLoc);
 }
 
+SourceRange ObjCPropertyImplDecl::getSourceRange() const {
+  SourceLocation EndLoc = getLocation();
+  if (IvarLoc.isValid())
+    EndLoc = IvarLoc;
 
+  return SourceRange(AtLoc, EndLoc);
+}
index d18efac5e2c1eb6baa2ac60d210da7d28117c328..c01bea9cb5a5edcd3b30fb8672e91efaf3dec56d 100644 (file)
@@ -1431,6 +1431,7 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
     IdentifierInfo *propertyIvar = 0;
     IdentifierInfo *propertyId = Tok.getIdentifierInfo();
     SourceLocation propertyLoc = ConsumeToken(); // consume property name
+    SourceLocation propertyIvarLoc;
     if (Tok.is(tok::equal)) {
       // property '=' ivar-name
       ConsumeToken(); // consume '='
@@ -1446,10 +1447,10 @@ Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
         break;
       }
       propertyIvar = Tok.getIdentifierInfo();
-      ConsumeToken(); // consume ivar-name
+      propertyIvarLoc = ConsumeToken(); // consume ivar-name
     }
     Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, true, ObjCImpDecl,
-                                  propertyId, propertyIvar);
+                                  propertyId, propertyIvar, propertyIvarLoc);
     if (Tok.isNot(tok::comma))
       break;
     ConsumeToken(); // consume ','
@@ -1489,7 +1490,7 @@ Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
     IdentifierInfo *propertyId = Tok.getIdentifierInfo();
     SourceLocation propertyLoc = ConsumeToken(); // consume property name
     Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, false, ObjCImpDecl,
-                                  propertyId, 0);
+                                  propertyId, 0, SourceLocation());
 
     if (Tok.isNot(tok::comma))
       break;
index fe2de27c6c85a76bf39f65740402acedf3ffb5ae..65002f3ea0376257fc7dfed3ce047de61b1e82dc 100644 (file)
@@ -318,7 +318,8 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
                                   bool Synthesize,
                                   Decl *ClassCatImpDecl,
                                   IdentifierInfo *PropertyId,
-                                  IdentifierInfo *PropertyIvar) {
+                                  IdentifierInfo *PropertyIvar,
+                                  SourceLocation PropertyIvarLoc) {
   ObjCContainerDecl *ClassImpDecl =
     cast_or_null<ObjCContainerDecl>(ClassCatImpDecl);
   // Make sure we have a context for the property implementation declaration.
@@ -474,7 +475,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
                                (Synthesize ?
                                 ObjCPropertyImplDecl::Synthesize
                                 : ObjCPropertyImplDecl::Dynamic),
-                               Ivar);
+                               Ivar, PropertyIvarLoc);
   if (ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) {
     getterMethod->createImplicitParams(Context, IDecl);
     if (getLangOptions().CPlusPlus && Synthesize &&
@@ -997,7 +998,8 @@ void Sema::DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl,
     // to help users.
     ActOnPropertyImplDecl(S, SourceLocation(), SourceLocation(),
                           true,IMPDecl,
-                          Prop->getIdentifier(), Prop->getIdentifier());
+                          Prop->getIdentifier(), Prop->getIdentifier(),
+                          SourceLocation());
   }
 }
 
index e49447063e7f70525a022cba7e794df1bb90c73f..9f5d0c11d1977f0b6a1ea7f6dd48e0949b23ff0b 100644 (file)
@@ -616,8 +616,9 @@ void ASTDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
   D->setAtLoc(ReadSourceLocation(Record, Idx));
   D->setPropertyDecl(
                cast_or_null<ObjCPropertyDecl>(Reader.GetDecl(Record[Idx++])));
-  D->setPropertyIvarDecl(
-                   cast_or_null<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
+  D->PropertyIvarDecl = 
+                   cast_or_null<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++]));
+  D->IvarLoc = ReadSourceLocation(Record, Idx);
   D->setGetterCXXConstructor(Reader.ReadExpr(F));
   D->setSetterCXXAssignment(Reader.ReadExpr(F));
 }
@@ -1467,7 +1468,8 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
   case DECL_OBJC_PROPERTY_IMPL:
     D = ObjCPropertyImplDecl::Create(*Context, 0, SourceLocation(),
                                      SourceLocation(), 0,
-                                     ObjCPropertyImplDecl::Dynamic, 0);
+                                     ObjCPropertyImplDecl::Dynamic, 0,
+                                     SourceLocation());
     break;
   case DECL_FIELD:
     D = FieldDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0, 0,
index 609a04432becd18110fd1a46458c9ab7d8113d4f..f7bb23764da5e3bcc7b9e407b55b022d1a589150 100644 (file)
@@ -511,6 +511,7 @@ void ASTDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
   Writer.AddSourceLocation(D->getLocStart(), Record);
   Writer.AddDeclRef(D->getPropertyDecl(), Record);
   Writer.AddDeclRef(D->getPropertyIvarDecl(), Record);
+  Writer.AddSourceLocation(D->getPropertyIvarDeclLoc(), Record);
   Writer.AddStmt(D->getGetterCXXConstructor());
   Writer.AddStmt(D->getSetterCXXAssignment());
   Code = serialization::DECL_OBJC_PROPERTY_IMPL;
index f2933c6588d8d915bc4f3cd5e8a680f3026e5c10..07e6020c74ba53ee63618319138dce9977b9215b 100644 (file)
@@ -479,4 +479,9 @@ static Rdar8595462_A * Rdar8595462_staticVar;
 // CHECK: Punctuation: "*" [111:26 - 111:27] ObjCPropertyDecl=foo2:111:27
 // CHECK: Identifier: "foo2" [111:27 - 111:31] ObjCPropertyDecl=foo2:111:27
 
-// FIXME: Very poor handling of @synthesized
+// CHECK: Punctuation: "@" [115:1 - 115:2] UnexposedDecl=foo:110:33 (Definition)
+// CHECK: Keyword: "synthesize" [115:2 - 115:12] UnexposedDecl=foo:110:33 (Definition)
+// CHECK: Identifier: "foo" [115:13 - 115:16] UnexposedDecl=foo:110:33 (Definition)
+// CHECK: Punctuation: "=" [115:17 - 115:18] UnexposedDecl=foo:110:33 (Definition)
+// CHECK: Identifier: "_foo" [115:19 - 115:23] MemberRef=_foo:107:8
+// CHECK: Punctuation: ";" [115:23 - 115:24] ObjCImplementationDecl=Rdar8595386:114:1 (Definition)
index f4e355707cab429ffb296da6f4e51fc4a6f094fd..17e2c7c5c7eafa405548b12c3fc8b49c2e80bb62 100644 (file)
@@ -293,6 +293,7 @@ public:
   // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
   bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
   bool VisitObjCClassDecl(ObjCClassDecl *D);
+  bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD);
   bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
   bool VisitNamespaceDecl(NamespaceDecl *D);
   bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
@@ -1044,6 +1045,13 @@ bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
   return false;
 }
 
+bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
+  if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
+    return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
+  
+  return false;
+}
+
 bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
   return VisitDeclContext(D);
 }