[cfe-commits] r64633 - /cfe/branches/Apple/objective-rewrite/tools/clang/Driver/RewriteObjC.cpp
Steve Naroff
snaroff at apple.com
Mon Feb 16 08:54:21 PST 2009
Author: snaroff
Date: Mon Feb 16 10:54:20 2009
New Revision: 64633
URL: http://llvm.org/viewvc/llvm-project?rev=64633&view=rev
Log:
Fix <rdar://problem/6562121> clang ObjC rewriter: @protocol(foo) returns nil.
Modified:
cfe/branches/Apple/objective-rewrite/tools/clang/Driver/RewriteObjC.cpp
Modified: cfe/branches/Apple/objective-rewrite/tools/clang/Driver/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/objective-rewrite/tools/clang/Driver/RewriteObjC.cpp?rev=64633&r1=64632&r2=64633&view=diff
==============================================================================
--- cfe/branches/Apple/objective-rewrite/tools/clang/Driver/RewriteObjC.cpp (original)
+++ cfe/branches/Apple/objective-rewrite/tools/clang/Driver/RewriteObjC.cpp Mon Feb 16 10:54:20 2009
@@ -59,6 +59,8 @@
llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
llvm::SmallVector<Stmt *, 32> Stmts;
llvm::SmallVector<int, 8> ObjCBcLabelNo;
+ // Remember all the @protocol(<expr>) expressions.
+ llvm::SmallVector<ObjCProtocolDecl *, 32> ProtocolExprDecls;
unsigned NumObjCStringLiterals;
@@ -297,11 +299,14 @@
const char *ClassName,
std::string &Result);
- void RewriteObjCProtocolsMetaData(const ObjCList<ObjCProtocolDecl>
- &Protocols,
- const char *prefix,
- const char *ClassName,
- std::string &Result);
+ void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol,
+ const char *prefix,
+ const char *ClassName,
+ std::string &Result);
+ void RewriteObjCProtocolListMetaData(const ObjCList<ObjCProtocolDecl> &Prots,
+ const char *prefix,
+ const char *ClassName,
+ std::string &Result);
void SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
std::string &Result);
void SynthesizeIvarOffsetComputation(ObjCImplementationDecl *IDecl,
@@ -2582,7 +2587,8 @@
&ProtoExprs[0],
ProtoExprs.size());
ReplaceStmt(Exp, ProtoExp);
- // delete Exp; leak for now, see RewritePropertySetter() usage for more info.
+ ProtocolExprDecls.push_back(Exp->getProtocol());
+ // delete Exp; leak for now, see RewritePropertySetter() usage for more info.
return ProtoExp;
}
@@ -2818,153 +2824,159 @@
Result += "\t }\n};\n";
}
-/// RewriteObjCProtocolsMetaData - Rewrite protocols meta-data.
+/// RewriteObjCProtocolMetaData - Rewrite protocols meta-data.
void RewriteObjC::
-RewriteObjCProtocolsMetaData(const ObjCList<ObjCProtocolDecl> &Protocols,
- const char *prefix,
- const char *ClassName,
- std::string &Result) {
+RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, const char *prefix,
+ const char *ClassName, std::string &Result) {
static bool objc_protocol_methods = false;
- if (Protocols.empty()) return;
-
- for (unsigned i = 0; i != Protocols.size(); i++) {
- ObjCProtocolDecl *PDecl = Protocols[i];
- // Output struct protocol_methods holder of method selector and type.
- if (!objc_protocol_methods && !PDecl->isForwardDecl()) {
- /* struct protocol_methods {
- SEL _cmd;
- char *method_types;
- }
- */
- Result += "\nstruct protocol_methods {\n";
- Result += "\tSEL _cmd;\n";
- Result += "\tchar *method_types;\n";
- Result += "};\n";
-
- objc_protocol_methods = true;
- }
- // Do not synthesize the protocol more than once.
- if (ObjCSynthesizedProtocols.count(PDecl))
- continue;
-
- if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
- unsigned NumMethods = PDecl->getNumInstanceMethods();
- /* struct _objc_protocol_method_list {
- int protocol_method_count;
- struct protocol_methods protocols[];
- }
- */
- Result += "\nstatic struct {\n";
- Result += "\tint protocol_method_count;\n";
- Result += "\tstruct protocol_methods protocols[";
- Result += utostr(NumMethods);
- Result += "];\n} _OBJC_PROTOCOL_INSTANCE_METHODS_";
- Result += PDecl->getNameAsString();
- Result += " __attribute__ ((used, section (\"__OBJC, __cat_inst_meth\")))= "
- "{\n\t" + utostr(NumMethods) + "\n";
-
- // Output instance methods declared in this protocol.
- for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(),
- E = PDecl->instmeth_end(); I != E; ++I) {
- if (I == PDecl->instmeth_begin())
- Result += "\t ,{{(SEL)\"";
- else
- Result += "\t ,{(SEL)\"";
- Result += (*I)->getSelector().getAsString().c_str();
- std::string MethodTypeString;
- Context->getObjCEncodingForMethodDecl((*I), MethodTypeString);
- Result += "\", \"";
- Result += MethodTypeString;
- Result += "\"}\n";
- }
- Result += "\t }\n};\n";
- }
-
- // Output class methods declared in this protocol.
- int NumMethods = PDecl->getNumClassMethods();
- if (NumMethods > 0) {
- /* struct _objc_protocol_method_list {
- int protocol_method_count;
- struct protocol_methods protocols[];
- }
- */
- Result += "\nstatic struct {\n";
- Result += "\tint protocol_method_count;\n";
- Result += "\tstruct protocol_methods protocols[";
- Result += utostr(NumMethods);
- Result += "];\n} _OBJC_PROTOCOL_CLASS_METHODS_";
- Result += PDecl->getNameAsString();
- Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
- "{\n\t";
- Result += utostr(NumMethods);
- Result += "\n";
-
- // Output instance methods declared in this protocol.
- for (ObjCProtocolDecl::classmeth_iterator I = PDecl->classmeth_begin(),
- E = PDecl->classmeth_end(); I != E; ++I) {
- if (I == PDecl->classmeth_begin())
- Result += "\t ,{{(SEL)\"";
- else
- Result += "\t ,{(SEL)\"";
- Result += (*I)->getSelector().getAsString().c_str();
- std::string MethodTypeString;
- Context->getObjCEncodingForMethodDecl((*I), MethodTypeString);
- Result += "\", \"";
- Result += MethodTypeString;
- Result += "\"}\n";
- }
- Result += "\t }\n};\n";
- }
- // Output:
- /* struct _objc_protocol {
- // Objective-C 1.0 extensions
- struct _objc_protocol_extension *isa;
- char *protocol_name;
- struct _objc_protocol **protocol_list;
- struct _objc_protocol_method_list *instance_methods;
- struct _objc_protocol_method_list *class_methods;
- };
+ // Output struct protocol_methods holder of method selector and type.
+ if (!objc_protocol_methods && !PDecl->isForwardDecl()) {
+ /* struct protocol_methods {
+ SEL _cmd;
+ char *method_types;
+ }
*/
- static bool objc_protocol = false;
- if (!objc_protocol) {
- Result += "\nstruct _objc_protocol {\n";
- Result += "\tstruct _objc_protocol_extension *isa;\n";
- Result += "\tchar *protocol_name;\n";
- Result += "\tstruct _objc_protocol **protocol_list;\n";
- Result += "\tstruct _objc_protocol_method_list *instance_methods;\n";
- Result += "\tstruct _objc_protocol_method_list *class_methods;\n";
- Result += "};\n";
-
- objc_protocol = true;
- }
+ Result += "\nstruct protocol_methods {\n";
+ Result += "\tSEL _cmd;\n";
+ Result += "\tchar *method_types;\n";
+ Result += "};\n";
- Result += "\nstatic struct _objc_protocol _OBJC_PROTOCOL_";
- Result += PDecl->getNameAsString();
- Result += " __attribute__ ((used, section (\"__OBJC, __protocol\")))= "
- "{\n\t0, \"";
+ objc_protocol_methods = true;
+ }
+ // Do not synthesize the protocol more than once.
+ if (ObjCSynthesizedProtocols.count(PDecl))
+ return;
+
+ if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
+ unsigned NumMethods = PDecl->getNumInstanceMethods();
+ /* struct _objc_protocol_method_list {
+ int protocol_method_count;
+ struct protocol_methods protocols[];
+ }
+ */
+ Result += "\nstatic struct {\n";
+ Result += "\tint protocol_method_count;\n";
+ Result += "\tstruct protocol_methods protocol_methods[";
+ Result += utostr(NumMethods);
+ Result += "];\n} _OBJC_PROTOCOL_INSTANCE_METHODS_";
Result += PDecl->getNameAsString();
- Result += "\", 0, ";
- if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
- Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
- Result += PDecl->getNameAsString();
- Result += ", ";
+ Result += " __attribute__ ((used, section (\"__OBJC, __cat_inst_meth\")))= "
+ "{\n\t" + utostr(NumMethods) + "\n";
+
+ // Output instance methods declared in this protocol.
+ for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(),
+ E = PDecl->instmeth_end(); I != E; ++I) {
+ if (I == PDecl->instmeth_begin())
+ Result += "\t ,{{(SEL)\"";
+ else
+ Result += "\t ,{(SEL)\"";
+ Result += (*I)->getSelector().getAsString().c_str();
+ std::string MethodTypeString;
+ Context->getObjCEncodingForMethodDecl((*I), MethodTypeString);
+ Result += "\", \"";
+ Result += MethodTypeString;
+ Result += "\"}\n";
}
- else
- Result += "0, ";
- if (PDecl->getNumClassMethods() > 0) {
- Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_";
- Result += PDecl->getNameAsString();
- Result += "\n";
+ Result += "\t }\n};\n";
+ }
+
+ // Output class methods declared in this protocol.
+ int NumMethods = PDecl->getNumClassMethods();
+ if (NumMethods > 0) {
+ /* struct _objc_protocol_method_list {
+ int protocol_method_count;
+ struct protocol_methods protocols[];
+ }
+ */
+ Result += "\nstatic struct {\n";
+ Result += "\tint protocol_method_count;\n";
+ Result += "\tstruct protocol_methods protocol_methods[";
+ Result += utostr(NumMethods);
+ Result += "];\n} _OBJC_PROTOCOL_CLASS_METHODS_";
+ Result += PDecl->getNameAsString();
+ Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
+ "{\n\t";
+ Result += utostr(NumMethods);
+ Result += "\n";
+
+ // Output instance methods declared in this protocol.
+ for (ObjCProtocolDecl::classmeth_iterator I = PDecl->classmeth_begin(),
+ E = PDecl->classmeth_end(); I != E; ++I) {
+ if (I == PDecl->classmeth_begin())
+ Result += "\t ,{{(SEL)\"";
+ else
+ Result += "\t ,{(SEL)\"";
+ Result += (*I)->getSelector().getAsString().c_str();
+ std::string MethodTypeString;
+ Context->getObjCEncodingForMethodDecl((*I), MethodTypeString);
+ Result += "\", \"";
+ Result += MethodTypeString;
+ Result += "\"}\n";
}
- else
- Result += "0\n";
+ Result += "\t }\n};\n";
+ }
+
+ // Output:
+ /* struct _objc_protocol {
+ // Objective-C 1.0 extensions
+ struct _objc_protocol_extension *isa;
+ char *protocol_name;
+ struct _objc_protocol **protocol_list;
+ struct _objc_protocol_method_list *instance_methods;
+ struct _objc_protocol_method_list *class_methods;
+ };
+ */
+ static bool objc_protocol = false;
+ if (!objc_protocol) {
+ Result += "\nstruct _objc_protocol {\n";
+ Result += "\tstruct _objc_protocol_extension *isa;\n";
+ Result += "\tchar *protocol_name;\n";
+ Result += "\tstruct _objc_protocol **protocol_list;\n";
+ Result += "\tstruct _objc_protocol_method_list *instance_methods;\n";
+ Result += "\tstruct _objc_protocol_method_list *class_methods;\n";
Result += "};\n";
- // Mark this protocol as having been generated.
- if (!ObjCSynthesizedProtocols.insert(PDecl))
- assert(false && "protocol already synthesized");
+ objc_protocol = true;
+ }
+
+ Result += "\nstatic struct _objc_protocol _OBJC_PROTOCOL_";
+ Result += PDecl->getNameAsString();
+ Result += " __attribute__ ((used, section (\"__OBJC, __protocol\")))= "
+ "{\n\t0, \"";
+ Result += PDecl->getNameAsString();
+ Result += "\", 0, ";
+ if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
+ Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
+ Result += PDecl->getNameAsString();
+ Result += ", ";
+ }
+ else
+ Result += "0, ";
+ if (PDecl->getNumClassMethods() > 0) {
+ Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_";
+ Result += PDecl->getNameAsString();
+ Result += "\n";
}
+ else
+ Result += "0\n";
+ Result += "};\n";
+
+ // Mark this protocol as having been generated.
+ if (!ObjCSynthesizedProtocols.insert(PDecl))
+ assert(false && "protocol already synthesized");
+
+}
+
+void RewriteObjC::
+RewriteObjCProtocolListMetaData(const ObjCList<ObjCProtocolDecl> &Protocols,
+ const char *prefix, const char *ClassName,
+ std::string &Result) {
+ if (Protocols.empty()) return;
+
+ for (unsigned i = 0; i != Protocols.size(); i++)
+ RewriteObjCProtocolMetaData(Protocols[i], prefix, ClassName, Result);
+
// Output the top lovel protocol meta-data for the class.
/* struct _objc_protocol_list {
struct _objc_protocol_list *next;
@@ -2998,6 +3010,7 @@
Result += "\t }\n};\n";
}
+
/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
/// implementation.
void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
@@ -3027,9 +3040,8 @@
// Protocols referenced in class declaration?
// Null CDecl is case of a category implementation with no category interface
if (CDecl)
- RewriteObjCProtocolsMetaData(CDecl->getReferencedProtocols(), "CATEGORY",
- FullCategoryName.c_str(), Result);
-
+ RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), "CATEGORY",
+ FullCategoryName.c_str(), Result);
/* struct _objc_category {
char *category_name;
char *class_name;
@@ -3205,10 +3217,9 @@
false, "", IDecl->getNameAsCString(), Result);
// Protocols referenced in class declaration?
- RewriteObjCProtocolsMetaData(CDecl->getReferencedProtocols(),
- "CLASS", CDecl->getNameAsCString(), Result);
+ RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(),
+ "CLASS", CDecl->getNameAsCString(), Result);
-
// Declaration of class/meta-class metadata
/* struct _objc_class {
struct _objc_class *isa; // or const char *root_class_name when metadata
@@ -3373,6 +3384,12 @@
// For each implemented category, write out all its meta data.
for (int i = 0; i < CatDefCount; i++)
RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
+
+ // Write out meta data for each @protocol(<expr>).
+ if (unsigned int nProtoExprs = ProtocolExprDecls.size()) {
+ for (unsigned int i = 0; i < nProtoExprs; i++)
+ RewriteObjCProtocolMetaData(ProtocolExprDecls[i], "", "", Result);
+ }
// Write objc_symtab metadata
/*
@@ -4520,7 +4537,7 @@
if (ClassImplementation.size() || CategoryImplementation.size())
RewriteImplementations();
-
+
// Get the buffer corresponding to MainFileID. If we haven't changed it, then
// we are done.
if (const RewriteBuffer *RewriteBuf =
@@ -4531,7 +4548,8 @@
fprintf(stderr, "No changes\n");
}
- if (ClassImplementation.size() || CategoryImplementation.size()) {
+ if (ClassImplementation.size() || CategoryImplementation.size() ||
+ ProtocolExprDecls.size()) {
// Rewrite Objective-c meta data*
std::string ResultStr;
SynthesizeMetaDataIntoBuffer(ResultStr);
More information about the cfe-commits
mailing list