[cfe-commits] r55461 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/CodeGen/CGObjCMac.cpp
Daniel Dunbar
daniel at zuster.org
Wed Aug 27 21:38:11 PDT 2008
Author: ddunbar
Date: Wed Aug 27 23:38:10 2008
New Revision: 55461
URL: http://llvm.org/viewvc/llvm-project?rev=55461&view=rev
Log:
NeXT: Emit mostly-correct property type encoding.
- Added ASTContext::getObjCEncodingForPropertyDecl.
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=55461&r1=55460&r2=55461&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Wed Aug 27 23:38:10 2008
@@ -38,6 +38,7 @@
class SourceManager;
// Decls
class Decl;
+ class ObjCPropertyDecl;
class RecordDecl;
class TagDecl;
class TranslationUnitDecl;
@@ -277,7 +278,15 @@
/// getObjCEncodingForMethodDecl - Return the encoded type for this method
/// declaration.
- void getObjCEncodingForMethodDecl(ObjCMethodDecl *Decl, std::string &S);
+ void getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S);
+
+ /// getObjCEncodingForPropertyDecl - Return the encoded type for
+ /// this method declaration. If non-NULL, Container must be either
+ /// an ObjCCategoryImplDecl or ObjCImplementationDecl; it should
+ /// only be NULL when getting encodings for protocol properties.
+ void getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *Decl,
+ const Decl *Container,
+ std::string &S);
/// getObjCEncodingTypeSize returns size of type for objective-c encoding
/// purpose.
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=55461&r1=55460&r2=55461&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Aug 27 23:38:10 2008
@@ -1396,9 +1396,10 @@
/// getObjCEncodingForMethodDecl - Return the encoded type for this method
/// declaration.
-void ASTContext::getObjCEncodingForMethodDecl(ObjCMethodDecl *Decl,
+void ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
std::string& S)
{
+ // FIXME: This is not very efficient.
// Encode type qualifer, 'in', 'inout', etc. for the return type.
getObjCEncodingForTypeQualifier(Decl->getObjCDeclQualifier(), S);
// Encode result type.
@@ -1436,6 +1437,91 @@
}
}
+/// getObjCEncodingForPropertyDecl - Return the encoded type for this
+/// method declaration. If non-NULL, Container must be either an
+/// ObjCCategoryImplDecl or ObjCImplementationDecl; it should only be
+/// NULL when getting encodings for protocol properties.
+void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
+ const Decl *Container,
+ std::string& S)
+{
+ // Collect information from the property implementation decl(s).
+ bool Dynamic = false;
+ ObjCPropertyImplDecl *SynthesizePID = 0;
+
+ // FIXME: Duplicated code due to poor abstraction.
+ if (Container) {
+ if (const ObjCCategoryImplDecl *CID =
+ dyn_cast<ObjCCategoryImplDecl>(Container)) {
+ for (ObjCCategoryImplDecl::propimpl_iterator
+ i = CID->propimpl_begin(), e = CID->propimpl_end(); i != e; ++i) {
+ ObjCPropertyImplDecl *PID = *i;
+ if (PID->getPropertyDecl() == PD) {
+ if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
+ Dynamic = true;
+ } else {
+ SynthesizePID = PID;
+ }
+ }
+ }
+ } else {
+ const ObjCImplementationDecl *OID = cast<ObjCImplementationDecl>(Container);
+ for (ObjCCategoryImplDecl::propimpl_iterator
+ i = OID->propimpl_begin(), e = OID->propimpl_end(); i != e; ++i) {
+ ObjCPropertyImplDecl *PID = *i;
+ if (PID->getPropertyDecl() == PD) {
+ if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
+ Dynamic = true;
+ } else {
+ SynthesizePID = PID;
+ }
+ }
+ }
+ }
+ }
+
+ // FIXME: This is not very efficient.
+ S = "T";
+
+ // Encode result type.
+ // FIXME: GCC uses a generating_property_type_encoding mode during
+ // this part. Investigate.
+ getObjCEncodingForType(PD->getType(), S, EncodingRecordTypes);
+
+ if (PD->isReadOnly()) {
+ S += ",R";
+ } else {
+ switch (PD->getSetterKind()) {
+ case ObjCPropertyDecl::Assign: break;
+ case ObjCPropertyDecl::Copy: S += ",C"; break;
+ case ObjCPropertyDecl::Retain: S += ",&"; break;
+ }
+ }
+
+ // It really isn't clear at all what this means, since properties
+ // are "dynamic by default".
+ if (Dynamic)
+ S += ",D";
+
+ if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) {
+ S += ",G";
+ S += PD->getGetterName().getName();
+ }
+
+ if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) {
+ S += ",S";
+ S += PD->getSetterName().getName();
+ }
+
+ if (SynthesizePID) {
+ const ObjCIvarDecl *OID = SynthesizePID->getPropertyIvarDecl();
+ S += ",V";
+ S += OID->getName();
+ }
+
+ // FIXME: OBJCGC: weak & strong
+}
+
void ASTContext::getObjCEncodingForType(QualType T, std::string& S,
llvm::SmallVector<const RecordType *, 8> &ERType) const {
// FIXME: This currently doesn't encode:
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=55461&r1=55460&r2=55461&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Wed Aug 27 23:38:10 2008
@@ -267,6 +267,7 @@
/// EmitPropertyList - Emit the given property list. The return
/// value has type PropertyListPtrTy.
llvm::Constant *EmitPropertyList(const std::string &Name,
+ const Decl *Container,
ObjCPropertyDecl * const *begin,
ObjCPropertyDecl * const *end);
@@ -315,8 +316,9 @@
/// name. The return value has type char *.
llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
- // FIXME: This is a horrible name too.
- llvm::Constant *GetPropertyType(const ObjCPropertyDecl *PD);
+ // FIXME: This can be dropped once string functions are unified.
+ llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
+ const Decl *Container);
/// GetNameForMethod - Return a name for the given method.
/// \param[out] NameOut - The return value.
@@ -623,6 +625,7 @@
OptClassMethods);
Values[3] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_PROTO_LIST_") +
PD->getName(),
+ 0,
PD->classprop_begin(),
PD->classprop_end());
@@ -702,13 +705,14 @@
};
*/
llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name,
+ const Decl *Container,
ObjCPropertyDecl * const *begin,
ObjCPropertyDecl * const *end) {
std::vector<llvm::Constant*> Properties, Prop(2);
for (; begin != end; ++begin) {
const ObjCPropertyDecl *PD = *begin;
Prop[0] = GetPropertyName(PD->getIdentifier());
- Prop[1] = GetPropertyType(PD);
+ Prop[1] = GetPropertyTypeString(PD, Container);
Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
Prop));
}
@@ -843,6 +847,7 @@
// If there is no category @interface then there can be no properties.
if (Category) {
Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName,
+ OCD,
Category->classprop_begin(),
Category->classprop_end());
} else {
@@ -1120,6 +1125,7 @@
Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Values[2] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") +
ID->getName(),
+ ID,
ID->getClassInterface()->classprop_begin(),
ID->getClassInterface()->classprop_end());
@@ -1599,9 +1605,11 @@
}
// FIXME: Merge into a single cstring creation function.
-llvm::Constant *CGObjCMac::GetPropertyType(const ObjCPropertyDecl *PD) {
- std::string TypeStr("MOOO!");
- //CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
+// FIXME: This Decl should be more precise.
+llvm::Constant *CGObjCMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
+ const Decl *Container) {
+ std::string TypeStr;
+ CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
}
@@ -1650,7 +1658,7 @@
}
for (std::set<IdentifierInfo*>::iterator i = DefinedSymbols.begin(),
e = DefinedSymbols.end(); i != e; ++i) {
- s << "\t.objc_class_name_" << (*i)->getName() << " = 0\n"
+ s << "\t.objc_class_name_" << (*i)->getName() << "=0\n"
<< "\t.globl .objc_class_name_" << (*i)->getName() << "\n";
}
CGM.getModule().appendModuleInlineAsm(s.str());
More information about the cfe-commits
mailing list