]> granicus.if.org Git - clang/commitdiff
Implement synthesizing properties by default.
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 9 Feb 2010 19:31:38 +0000 (19:31 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 9 Feb 2010 19:31:38 +0000 (19:31 +0000)
This is a non-fragile-abi feature only. Since it
breaks existing code, it is currently placed under
-fobjc-nonfragile-abi2 option for test purposes only
until further notice. WIP.

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

include/clang/Basic/DiagnosticFrontendKinds.td
include/clang/Basic/LangOptions.h
include/clang/Driver/CC1Options.td
include/clang/Driver/Options.td
lib/Frontend/CompilerInvocation.cpp
lib/Frontend/PCHReader.cpp
lib/Frontend/PCHWriter.cpp
lib/Sema/Sema.h
lib/Sema/SemaDeclObjC.cpp
lib/Sema/SemaExpr.cpp

index 01104fc543326945d11d54d408d29fefd5a7f8ed..aa91d463502b3481e07bf5254c8054ceea74d1d2 100644 (file)
@@ -109,6 +109,10 @@ def warn_pch_objective_c2 : Error<
 def warn_pch_nonfragile_abi : Error<
     "PCH file was compiled with the %select{32-bit|non-fragile}0 Objective-C "
     "ABI but the %select{32-bit|non-fragile}1 Objective-C ABI is selected">;
+def warn_pch_nonfragile_abi2 : Error<
+    "PCH file was compiled with the %select{32-bit|enhanced non-fragile}0 "
+    "Objective-C ABI but the %select{32-bit|enhanced non-fragile}1 "
+    "Objective-C ABI is selected">;
 def warn_pch_extensions : Error<
     "extensions were %select{enabled|disabled}0 in PCH file but are "
     "currently %select{enabled|disabled}1">;
index 2abf9ef7a08dc48ab2acf5ff7d63c0ddd5daed3e..d97e61cc16604ac68b12441178ca506d590ab74b 100644 (file)
@@ -40,6 +40,7 @@ public:
   unsigned ObjC1             : 1;  // Objective-C 1 support enabled.
   unsigned ObjC2             : 1;  // Objective-C 2 support enabled.
   unsigned ObjCNonFragileABI : 1;  // Objective-C modern abi enabled
+  unsigned ObjCNonFragileABI2 : 1;  // Objective-C enhanced modern abi enabled
 
   unsigned PascalStrings     : 1;  // Allow Pascal strings
   unsigned WritableStrings   : 1;  // Allow writable strings
@@ -124,7 +125,7 @@ public:
     Trigraphs = BCPLComment = Bool = DollarIdents = AsmPreprocessor = 0;
     GNUMode = ImplicitInt = Digraphs = 0;
     HexFloats = 0;
-    GC = ObjC1 = ObjC2 = ObjCNonFragileABI = 0;
+    GC = ObjC1 = ObjC2 = ObjCNonFragileABI = ObjCNonFragileABI2 = 0;
     C99 = Microsoft = CPlusPlus = CPlusPlus0x = 0;
     CXXOperatorNames = PascalStrings = WritableStrings = 0;
     Exceptions = Freestanding = NoBuiltin = 0;
index f0db6e7caff7c1320d58be36275e50f4dda8f2e3..5f1983d4cb36f719d984f6e379ca33c3a2a78f9e 100644 (file)
@@ -360,6 +360,8 @@ def print_ivar_layout : Flag<"-print-ivar-layout">,
   HelpText<"Enable Objective-C Ivar layout bitmap print trace">;
 def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">,
   HelpText<"enable objective-c's nonfragile abi">;
+def fobjc_nonfragile_abi2 : Flag<"-fobjc-nonfragile-abi2">,
+  HelpText<"enable objective-c's enhanced nonfragile abi">;
 def ftrapv : Flag<"-ftrapv">,
   HelpText<"Trap on integer overflow">;
 def pic_level : Separate<"-pic-level">,
index 767123b14b7ab040e80ad232344376237d9ebc87..e42e2cc9c9b422122bac5d638d50232e6105b016 100644 (file)
@@ -323,6 +323,7 @@ def fobjc_gc : Flag<"-fobjc-gc">, Group<f_Group>;
 def fobjc_legacy_dispatch : Flag<"-fobjc-legacy-dispatch">, Group<f_Group>;
 def fobjc_new_property : Flag<"-fobjc-new-property">, Group<clang_ignored_f_Group>;
 def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">, Group<f_Group>;
+def fobjc_nonfragile_abi2 : Flag<"-fobjc-nonfragile-abi2">, Group<f_Group>;
 def fobjc_sender_dependent_dispatch : Flag<"-fobjc-sender-dependent-dispatch">, Group<f_Group>;
 def fobjc : Flag<"-fobjc">, Group<f_Group>;
 def fomit_frame_pointer : Flag<"-fomit-frame-pointer">, Group<f_Group>;
index 006f3c095cab957a888dc78358c0a022a61bc7d7..35cfee85fcafda3269ef9ea5a96cb79e3e9c588c 100644 (file)
@@ -459,6 +459,8 @@ static void LangOptsToArgs(const LangOptions &Opts,
     Res.push_back("-fms-extensions");
   if (Opts.ObjCNonFragileABI)
     Res.push_back("-fobjc-nonfragile-abi");
+  if (Opts.ObjCNonFragileABI2)
+    Res.push_back("-fobjc-nonfragile-abi2");
   // NoInline is implicit.
   if (!Opts.CXXOperatorNames)
     Res.push_back("-fno-operator-names");
@@ -1181,6 +1183,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args,
   Opts.ObjCConstantStringClass = getLastArgValue(Args,
                                                  OPT_fconstant_string_class);
   Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
+  Opts.ObjCNonFragileABI2 = Args.hasArg(OPT_fobjc_nonfragile_abi2);
+  if (Opts.ObjCNonFragileABI2)
+    Opts.ObjCNonFragileABI = true;
   Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
   Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
   Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
index 1ed5260a8833fb7bc71a36d3497ed2796a8ea3b5..9ab3b7a0a2610463805032f1c6cd5bdfbaa1f206 100644 (file)
@@ -72,6 +72,7 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) {
   PARSE_LANGOPT_IMPORTANT(ObjC1, diag::warn_pch_objective_c);
   PARSE_LANGOPT_IMPORTANT(ObjC2, diag::warn_pch_objective_c2);
   PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI, diag::warn_pch_nonfragile_abi);
+  PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI2, diag::warn_pch_nonfragile_abi2);
   PARSE_LANGOPT_BENIGN(PascalStrings);
   PARSE_LANGOPT_BENIGN(WritableStrings);
   PARSE_LANGOPT_IMPORTANT(LaxVectorConversions,
@@ -1740,6 +1741,7 @@ bool PCHReader::ParseLanguageOptions(
     PARSE_LANGOPT(ObjC1);
     PARSE_LANGOPT(ObjC2);
     PARSE_LANGOPT(ObjCNonFragileABI);
+    PARSE_LANGOPT(ObjCNonFragileABI2);
     PARSE_LANGOPT(PascalStrings);
     PARSE_LANGOPT(WritableStrings);
     PARSE_LANGOPT(LaxVectorConversions);
index 5085cf43d023c9f01ab75a5ea626e7b07eaa4600..45d9b1baced0d6d6642dd27811fdc32309c3011a 100644 (file)
@@ -748,7 +748,10 @@ void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) {
 
   Record.push_back(LangOpts.ObjC1);  // Objective-C 1 support enabled.
   Record.push_back(LangOpts.ObjC2);  // Objective-C 2 support enabled.
-  Record.push_back(LangOpts.ObjCNonFragileABI);  // Objective-C modern abi enabled
+  Record.push_back(LangOpts.ObjCNonFragileABI);  // Objective-C 
+                                                 // modern abi enabled.
+  Record.push_back(LangOpts.ObjCNonFragileABI2); // Objective-C enhanced 
+                                                 // modern abi enabled.
 
   Record.push_back(LangOpts.PascalStrings);  // Allow Pascal strings
   Record.push_back(LangOpts.WritableStrings);  // Allow writable strings
index ead808fdeb1eeac5639437fb3b5107943fc88f93..bf6888762f3649d838ca3c577eb04590a3f7e9ca 100644 (file)
@@ -1358,6 +1358,11 @@ public:
   void CollectImmediateProperties(ObjCContainerDecl *CDecl,
                   llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap);
   
+  /// LookupPropertyDecl - Looks up a property in the current class and all
+  /// its protocols.
+  ObjCPropertyDecl *LookupPropertyDecl(const ObjCContainerDecl *CDecl, 
+                                       IdentifierInfo *II);
+  
   /// AtomicPropertySetterGetterRules - This routine enforces the rule (via
   /// warning) when atomic property has one but not the other user-declared
   /// setter or getter.
index 1b07d19882e0b34fd9a3ef8c30d05ec73d77f56a..c0e8219f67fcf677bdb34d132a982e8f27a6c480 100644 (file)
@@ -1127,6 +1127,46 @@ void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl,
   }
 }
 
+/// LookupPropertyDecl - Looks up a property in the current class and all
+/// its protocols.
+ObjCPropertyDecl *Sema::LookupPropertyDecl(const ObjCContainerDecl *CDecl, 
+                                     IdentifierInfo *II) {
+  if (const ObjCInterfaceDecl *IDecl = 
+        dyn_cast<ObjCInterfaceDecl>(CDecl)) {
+    for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(),
+         E = IDecl->prop_end(); P != E; ++P) {
+      ObjCPropertyDecl *Prop = (*P);
+      if (Prop->getIdentifier() == II)
+        return Prop;
+    }
+    // scan through class's protocols.
+    for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
+         E = IDecl->protocol_end(); PI != E; ++PI) {
+      ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II);
+      if (Prop)
+        return Prop;
+    }
+  }
+  else if (const ObjCProtocolDecl *PDecl = 
+            dyn_cast<ObjCProtocolDecl>(CDecl)) {
+    for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
+         E = PDecl->prop_end(); P != E; ++P) {
+      ObjCPropertyDecl *Prop = (*P);
+      if (Prop->getIdentifier() == II)
+        return Prop;
+    }
+    // scan through protocol's protocols.
+    for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
+         E = PDecl->protocol_end(); PI != E; ++PI) {
+      ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II);
+      if (Prop)
+        return Prop;
+    }
+  }
+  return 0;
+}
+
+
 void Sema::DiagnoseUnimplementedProperties(ObjCImplDecl* IMPDecl,
                                       ObjCContainerDecl *CDecl,
                                       const llvm::DenseSet<Selector>& InsMap) {
@@ -1149,7 +1189,14 @@ void Sema::DiagnoseUnimplementedProperties(ObjCImplDecl* IMPDecl,
         Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional ||
         PropImplMap.count(Prop))
       continue;
-  
+    if (LangOpts.ObjCNonFragileABI2) {
+      ActOnPropertyImplDecl(IMPDecl->getLocation(),
+                            SourceLocation(),
+                            true, DeclPtrTy::make(IMPDecl), 
+                            Prop->getIdentifier(),
+                            Prop->getIdentifier());
+      continue;
+    }
     if (!InsMap.count(Prop->getGetterName())) {
       Diag(Prop->getLocation(),
            isa<ObjCCategoryDecl>(CDecl) ? 
index abb4e786d6c41fdc642960148006bfe44be9f1b2..0da57330eeb67e4fff32481e2852b85d885deb86 100644 (file)
@@ -1271,9 +1271,9 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
   else
     LookForIvars = (Lookup.isSingleResult() &&
                     Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod());
-
+  ObjCInterfaceDecl *IFace = 0;
   if (LookForIvars) {
-    ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface();
+    IFace = getCurMethodDecl()->getClassInterface();
     ObjCInterfaceDecl *ClassDeclared;
     if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) {
       // Diagnose using an ivar in a class method.
@@ -1342,6 +1342,24 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
       }
     }
   }
+  if (LangOpts.ObjCNonFragileABI2 && LookForIvars && Lookup.empty()) {
+    // Find property name matching variable name.
+    ObjCPropertyDecl *Prop = LookupPropertyDecl(IFace, II);
+    if (Prop && !Prop->isInvalidDecl()) {
+      DeclContext *EnclosingContext = cast_or_null<DeclContext>(IFace);
+      QualType PropType = Context.getCanonicalType(Prop->getType());
+      assert(EnclosingContext &&
+             "null DeclContext for synthesized ivar - LookupInObjCMethod");
+      ObjCIvarDecl *Ivar = ObjCIvarDecl::Create(Context, EnclosingContext, 
+                                                Prop->getLocation(),
+                                                II, PropType, /*Dinfo=*/0,
+                                                ObjCIvarDecl::Public,
+                                                (Expr *)0);
+      Ivar->setLexicalDeclContext(IFace);
+      IFace->addDecl(Ivar);
+      return LookupInObjCMethod(Lookup, S, II, AllowBuiltinCreation);
+    }
+  }
   // Sentinel value saying that we didn't do anything special.
   return Owned((Expr*) 0);
 }