summaryrefslogtreecommitdiffstats
path: root/lib/Frontend/RewriteObjC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Frontend/RewriteObjC.cpp')
-rw-r--r--lib/Frontend/RewriteObjC.cpp448
1 files changed, 274 insertions, 174 deletions
diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp
index 35d8dde..9dade66 100644
--- a/lib/Frontend/RewriteObjC.cpp
+++ b/lib/Frontend/RewriteObjC.cpp
@@ -124,8 +124,10 @@ namespace {
llvm::DenseMap<BlockDeclRefExpr *, CallExpr *> BlockCallExprs;
// Block related declarations.
- llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDecls;
- llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDecls;
+ llvm::SmallVector<ValueDecl *, 8> BlockByCopyDecls;
+ llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
+ llvm::SmallVector<ValueDecl *, 8> BlockByRefDecls;
+ llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
@@ -212,11 +214,10 @@ namespace {
<< Old->getSourceRange();
}
- void InsertText(SourceLocation Loc, const char *StrData, unsigned StrLen,
+ void InsertText(SourceLocation Loc, llvm::StringRef Str,
bool InsertAfter = true) {
// If insertion succeeded or warning disabled return with no warning.
- if (!Rewrite.InsertText(Loc, llvm::StringRef(StrData, StrLen),
- InsertAfter) ||
+ if (!Rewrite.InsertText(Loc, Str, InsertAfter) ||
SilenceRewriteMacroWarning)
return;
@@ -232,10 +233,9 @@ namespace {
}
void ReplaceText(SourceLocation Start, unsigned OrigLength,
- const char *NewStr, unsigned NewLength) {
+ llvm::StringRef Str) {
// If removal succeeded or warning disabled return with no warning.
- if (!Rewrite.ReplaceText(Start, OrigLength,
- llvm::StringRef(NewStr, NewLength)) ||
+ if (!Rewrite.ReplaceText(Start, OrigLength, Str) ||
SilenceRewriteMacroWarning)
return;
@@ -263,6 +263,7 @@ namespace {
void RewriteFunctionDecl(FunctionDecl *FD);
void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD);
void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
+ void RewriteTypeOfDecl(VarDecl *VD);
void RewriteObjCQualifiedInterfaceTypes(Expr *E);
bool needToScanForQualifiers(QualType T);
ObjCInterfaceDecl *isSuperReceiver(Expr *recExpr);
@@ -278,7 +279,9 @@ namespace {
ParentMap *PropParentMap; // created lazily.
Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
- Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, SourceLocation OrigStart);
+ Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, SourceLocation OrigStart,
+ bool &replaced);
+ Stmt *RewriteObjCNestedIvarRefExpr(Stmt *S, bool &replaced);
Stmt *RewritePropertyGetter(ObjCPropertyRefExpr *PropRefExpr);
Stmt *RewritePropertySetter(BinaryOperator *BinOp, Expr *newStmt,
SourceRange SrcRange);
@@ -632,6 +635,9 @@ void RewriteObjC::Initialize(ASTContext &context) {
//===----------------------------------------------------------------------===//
void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) {
+ if (Diags.hasErrorOccurred())
+ return;
+
// Two cases: either the decl could be in the main file, or it could be in a
// #included file. If the former, rewrite it now. If the later, check to see
// if we rewrote the #include/#import.
@@ -681,7 +687,6 @@ void RewriteObjC::RewriteInclude() {
const char *MainBufStart = MainBuf.first;
const char *MainBufEnd = MainBuf.second;
size_t ImportLen = strlen("import");
- size_t IncludeLen = strlen("include");
// Loop over the whole file, looking for includes.
for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
@@ -695,7 +700,7 @@ void RewriteObjC::RewriteInclude() {
// replace import with include
SourceLocation ImportLoc =
LocStart.getFileLocWithOffset(BufPtr-MainBufStart);
- ReplaceText(ImportLoc, ImportLen, "include", IncludeLen);
+ ReplaceText(ImportLoc, ImportLen, "include");
BufPtr += ImportLen;
}
}
@@ -728,7 +733,7 @@ void RewriteObjC::RewriteTabs() {
TabLoc = TabLoc.getFileLocWithOffset(BufPtr-MainBufStart);
// Rewrite the single tab character into a sequence of spaces.
- ReplaceText(TabLoc, 1, " ", Spaces);
+ ReplaceText(TabLoc, 1, llvm::StringRef(" ", Spaces));
}
}
@@ -746,7 +751,7 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
ObjCImplementationDecl *IMD,
ObjCCategoryImplDecl *CID) {
SourceLocation startLoc = PID->getLocStart();
- InsertText(startLoc, "// ", 3);
+ InsertText(startLoc, "// ");
const char *startBuf = SM->getCharacterData(startLoc);
assert((*startBuf == '@') && "bogus @synthesize location");
const char *semiBuf = strchr(startBuf, ';');
@@ -774,7 +779,7 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
// See objc-act.c:objc_synthesize_new_getter() for details.
Getr += "return " + getIvarAccessString(ClassDecl, OID);
Getr += "; }";
- InsertText(onePastSemiLoc, Getr.c_str(), Getr.size());
+ InsertText(onePastSemiLoc, Getr);
if (PD->isReadOnly())
return;
@@ -789,7 +794,7 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
Setr += getIvarAccessString(ClassDecl, OID) + " = ";
Setr += PD->getNameAsCString();
Setr += "; }";
- InsertText(onePastSemiLoc, Setr.c_str(), Setr.size());
+ InsertText(onePastSemiLoc, Setr);
}
void RewriteObjC::RewriteForwardClassDecl(ObjCClassDecl *ClassDecl) {
@@ -828,8 +833,7 @@ void RewriteObjC::RewriteForwardClassDecl(ObjCClassDecl *ClassDecl) {
}
// Replace the @class with typedefs corresponding to the classes.
- ReplaceText(startLoc, semiPtr-startBuf+1,
- typedefString.c_str(), typedefString.size());
+ ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
}
void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
@@ -842,17 +846,17 @@ void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
if (SM->getInstantiationLineNumber(LocEnd) >
SM->getInstantiationLineNumber(LocStart)) {
- InsertText(LocStart, "#if 0\n", 6);
- ReplaceText(LocEnd, 1, ";\n#endif\n", 9);
+ InsertText(LocStart, "#if 0\n");
+ ReplaceText(LocEnd, 1, ";\n#endif\n");
} else {
- InsertText(LocStart, "// ", 3);
+ InsertText(LocStart, "// ");
}
}
void RewriteObjC::RewriteProperty(ObjCPropertyDecl *prop) {
SourceLocation Loc = prop->getAtLoc();
- ReplaceText(Loc, 0, "// ", 3);
+ ReplaceText(Loc, 0, "// ");
// FIXME: handle properties that are declared across multiple lines.
}
@@ -860,8 +864,12 @@ void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
SourceLocation LocStart = CatDecl->getLocStart();
// FIXME: handle category headers that are declared across multiple lines.
- ReplaceText(LocStart, 0, "// ", 3);
+ ReplaceText(LocStart, 0, "// ");
+ for (ObjCCategoryDecl::prop_iterator I = CatDecl->prop_begin(),
+ E = CatDecl->prop_end(); I != E; ++I)
+ RewriteProperty(*I);
+
for (ObjCCategoryDecl::instmeth_iterator
I = CatDecl->instmeth_begin(), E = CatDecl->instmeth_end();
I != E; ++I)
@@ -872,7 +880,7 @@ void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
RewriteMethodDeclaration(*I);
// Lastly, comment out the @end.
- ReplaceText(CatDecl->getAtEndRange().getBegin(), 0, "// ", 3);
+ ReplaceText(CatDecl->getAtEndRange().getBegin(), 0, "// ");
}
void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
@@ -881,7 +889,7 @@ void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
SourceLocation LocStart = PDecl->getLocStart();
// FIXME: handle protocol headers that are declared across multiple lines.
- ReplaceText(LocStart, 0, "// ", 3);
+ ReplaceText(LocStart, 0, "// ");
for (ObjCProtocolDecl::instmeth_iterator
I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
@@ -894,24 +902,20 @@ void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
// Lastly, comment out the @end.
SourceLocation LocEnd = PDecl->getAtEndRange().getBegin();
- ReplaceText(LocEnd, 0, "// ", 3);
+ ReplaceText(LocEnd, 0, "// ");
// Must comment out @optional/@required
const char *startBuf = SM->getCharacterData(LocStart);
const char *endBuf = SM->getCharacterData(LocEnd);
for (const char *p = startBuf; p < endBuf; p++) {
if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) {
- std::string CommentedOptional = "/* @optional */";
SourceLocation OptionalLoc = LocStart.getFileLocWithOffset(p-startBuf);
- ReplaceText(OptionalLoc, strlen("@optional"),
- CommentedOptional.c_str(), CommentedOptional.size());
+ ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */");
}
else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) {
- std::string CommentedRequired = "/* @required */";
SourceLocation OptionalLoc = LocStart.getFileLocWithOffset(p-startBuf);
- ReplaceText(OptionalLoc, strlen("@required"),
- CommentedRequired.c_str(), CommentedRequired.size());
+ ReplaceText(OptionalLoc, strlen("@required"), "/* @required */");
}
}
@@ -922,7 +926,7 @@ void RewriteObjC::RewriteForwardProtocolDecl(ObjCForwardProtocolDecl *PDecl) {
if (LocStart.isInvalid())
assert(false && "Invalid SourceLocation");
// FIXME: handle forward protocol that are declared across multiple lines.
- ReplaceText(LocStart, 0, "// ", 3);
+ ReplaceText(LocStart, 0, "// ");
}
void RewriteObjC::RewriteObjCMethodDecl(ObjCMethodDecl *OMD,
@@ -1050,10 +1054,7 @@ void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID);
ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID);
- if (IMD)
- InsertText(IMD->getLocStart(), "// ", 3);
- else
- InsertText(CID->getLocStart(), "// ", 3);
+ InsertText(IMD ? IMD->getLocStart() : CID->getLocStart(), "// ");
for (ObjCCategoryImplDecl::instmeth_iterator
I = IMD ? IMD->instmeth_begin() : CID->instmeth_begin(),
@@ -1067,8 +1068,7 @@ void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
const char *startBuf = SM->getCharacterData(LocStart);
const char *endBuf = SM->getCharacterData(LocEnd);
- ReplaceText(LocStart, endBuf-startBuf,
- ResultStr.c_str(), ResultStr.size());
+ ReplaceText(LocStart, endBuf-startBuf, ResultStr);
}
for (ObjCCategoryImplDecl::classmeth_iterator
@@ -1083,8 +1083,7 @@ void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
const char *startBuf = SM->getCharacterData(LocStart);
const char *endBuf = SM->getCharacterData(LocEnd);
- ReplaceText(LocStart, endBuf-startBuf,
- ResultStr.c_str(), ResultStr.size());
+ ReplaceText(LocStart, endBuf-startBuf, ResultStr);
}
for (ObjCCategoryImplDecl::propimpl_iterator
I = IMD ? IMD->propimpl_begin() : CID->propimpl_begin(),
@@ -1093,10 +1092,7 @@ void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
RewritePropertyImplDecl(*I, IMD, CID);
}
- if (IMD)
- InsertText(IMD->getLocEnd(), "// ", 3);
- else
- InsertText(CID->getLocEnd(), "// ", 3);
+ InsertText(IMD ? IMD->getLocEnd() : CID->getLocEnd(), "// ");
}
void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
@@ -1130,7 +1126,7 @@ void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
RewriteMethodDeclaration(*I);
// Lastly, comment out the @end.
- ReplaceText(ClassDecl->getAtEndRange().getBegin(), 0, "// ", 3);
+ ReplaceText(ClassDecl->getAtEndRange().getBegin(), 0, "// ");
}
Stmt *RewriteObjC::RewritePropertySetter(BinaryOperator *BinOp, Expr *newStmt,
@@ -1149,7 +1145,7 @@ Stmt *RewriteObjC::RewritePropertySetter(BinaryOperator *BinOp, Expr *newStmt,
// This allows us to handle chain/nested property getters.
Receiver = PropGetters[PRE];
}
- MsgExpr = new (Context) ObjCMessageExpr(dyn_cast<Expr>(Receiver),
+ MsgExpr = new (Context) ObjCMessageExpr(*Context, dyn_cast<Expr>(Receiver),
PDecl->getSetterName(), PDecl->getType(),
PDecl->getSetterMethodDecl(),
SourceLocation(), SourceLocation(),
@@ -1178,7 +1174,7 @@ Stmt *RewriteObjC::RewritePropertyGetter(ObjCPropertyRefExpr *PropRefExpr) {
// This allows us to handle chain/nested property getters.
Receiver = PropGetters[PRE];
}
- MsgExpr = new (Context) ObjCMessageExpr(dyn_cast<Expr>(Receiver),
+ MsgExpr = new (Context) ObjCMessageExpr(*Context, dyn_cast<Expr>(Receiver),
PDecl->getGetterName(), PDecl->getType(),
PDecl->getGetterMethodDecl(),
SourceLocation(), SourceLocation(),
@@ -1209,14 +1205,15 @@ Stmt *RewriteObjC::RewritePropertyGetter(ObjCPropertyRefExpr *PropRefExpr) {
}
Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
- SourceLocation OrigStart) {
+ SourceLocation OrigStart,
+ bool &replaced) {
ObjCIvarDecl *D = IV->getDecl();
const Expr *BaseExpr = IV->getBase();
if (CurMethodDef) {
- if (BaseExpr->getType()->isObjCObjectPointerType() &&
- isa<DeclRefExpr>(BaseExpr)) {
+ if (BaseExpr->getType()->isObjCObjectPointerType()) {
ObjCInterfaceType *iFaceDecl =
dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
+ assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null");
// lookup which class implements the instance variable.
ObjCInterfaceDecl *clsDeclared = 0;
iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
@@ -1226,7 +1223,7 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
// Synthesize an explicit cast to gain access to the ivar.
std::string RecName = clsDeclared->getIdentifier()->getName();
RecName += "_IMPL";
- IdentifierInfo *II = &Context->Idents.get(RecName.c_str());
+ IdentifierInfo *II = &Context->Idents.get(RecName);
RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
SourceLocation(), II);
assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
@@ -1238,17 +1235,16 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(),
IV->getBase()->getLocEnd(),
castExpr);
+ replaced = true;
if (IV->isFreeIvar() &&
CurMethodDef->getClassInterface() == iFaceDecl->getDecl()) {
MemberExpr *ME = new (Context) MemberExpr(PE, true, D,
IV->getLocation(),
D->getType());
- ReplaceStmt(IV, ME);
// delete IV; leak for now, see RewritePropertySetter() usage for more info.
return ME;
}
-
- ReplaceStmt(IV->getBase(), PE);
+ // Get the new text
// Cannot delete IV->getBase(), since PE points to it.
// Replace the old base with the cast. This is important when doing
// embedded rewrites. For example, [newInv->_container addObject:0].
@@ -1272,7 +1268,7 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
// Synthesize an explicit cast to gain access to the ivar.
std::string RecName = clsDeclared->getIdentifier()->getName();
RecName += "_IMPL";
- IdentifierInfo *II = &Context->Idents.get(RecName.c_str());
+ IdentifierInfo *II = &Context->Idents.get(RecName);
RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
SourceLocation(), II);
assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
@@ -1283,7 +1279,7 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
// Don't forget the parens to enforce the proper binding.
ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(),
IV->getBase()->getLocEnd(), castExpr);
- ReplaceStmt(IV->getBase(), PE);
+ replaced = true;
// Cannot delete IV->getBase(), since PE points to it.
// Replace the old base with the cast. This is important when doing
// embedded rewrites. For example, [newInv->_container addObject:0].
@@ -1294,6 +1290,28 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
return IV;
}
+Stmt *RewriteObjC::RewriteObjCNestedIvarRefExpr(Stmt *S, bool &replaced) {
+ for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+ CI != E; ++CI) {
+ if (*CI) {
+ Stmt *newStmt = RewriteObjCNestedIvarRefExpr(*CI, replaced);
+ if (newStmt)
+ *CI = newStmt;
+ }
+ }
+ if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
+ SourceRange OrigStmtRange = S->getSourceRange();
+ Stmt *newStmt = RewriteObjCIvarRefExpr(IvarRefExpr, OrigStmtRange.getBegin(),
+ replaced);
+ return newStmt;
+ }
+ if (ObjCMessageExpr *MsgRefExpr = dyn_cast<ObjCMessageExpr>(S)) {
+ Stmt *newStmt = SynthMessageExpr(MsgRefExpr);
+ return newStmt;
+ }
+ return S;
+}
+
/// SynthCountByEnumWithState - To print:
/// ((unsigned int (*)
/// (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
@@ -1326,7 +1344,7 @@ Stmt *RewriteObjC::RewriteBreakStmt(BreakStmt *S) {
SourceLocation startLoc = S->getLocStart();
buf = "goto __break_label_";
buf += utostr(ObjCBcLabelNo.back());
- ReplaceText(startLoc, strlen("break"), buf.c_str(), buf.size());
+ ReplaceText(startLoc, strlen("break"), buf);
return 0;
}
@@ -1343,7 +1361,7 @@ Stmt *RewriteObjC::RewriteContinueStmt(ContinueStmt *S) {
SourceLocation startLoc = S->getLocStart();
buf = "goto __continue_label_";
buf += utostr(ObjCBcLabelNo.back());
- ReplaceText(startLoc, strlen("continue"), buf.c_str(), buf.size());
+ ReplaceText(startLoc, strlen("continue"), buf);
return 0;
}
@@ -1442,8 +1460,7 @@ Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
startCollectionBuf += 3;
// Replace: "for (type element in" with string constructed thus far.
- ReplaceText(startLoc, startCollectionBuf - startBuf,
- buf.c_str(), buf.size());
+ ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
// Replace ')' in for '(' type elem in collection ')' with ';'
SourceLocation rightParenLoc = S->getRParenLoc();
const char *rparenBuf = SM->getCharacterData(rightParenLoc);
@@ -1484,7 +1501,7 @@ Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
buf += elementTypeAsString;
buf += ")enumState.itemsPtr[counter++];";
// Replace ')' in for '(' type elem in collection ')' with all of these.
- ReplaceText(lparenLoc, 1, buf.c_str(), buf.size());
+ ReplaceText(lparenLoc, 1, buf);
/// __continue_label: ;
/// } while (counter < limit);
@@ -1525,7 +1542,7 @@ Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
// FIXME: If this should support Obj-C++, support CXXTryStmt
if (isa<CompoundStmt>(S->getBody())) {
SourceLocation endBodyLoc = OrigEnd.getFileLocWithOffset(1);
- InsertText(endBodyLoc, buf.c_str(), buf.size());
+ InsertText(endBodyLoc, buf);
} else {
/* Need to treat single statements specially. For example:
*
@@ -1538,7 +1555,7 @@ Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
const char *semiBuf = strchr(stmtBuf, ';');
assert(semiBuf && "Can't find ';'");
SourceLocation endBodyLoc = OrigEnd.getFileLocWithOffset(semiBuf-stmtBuf+1);
- InsertText(endBodyLoc, buf.c_str(), buf.size());
+ InsertText(endBodyLoc, buf);
}
Stmts.pop_back();
ObjCBcLabelNo.pop_back();
@@ -1562,7 +1579,7 @@ Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
buf = "objc_sync_enter((id)";
const char *lparenBuf = startBuf;
while (*lparenBuf != '(') lparenBuf++;
- ReplaceText(startLoc, lparenBuf-startBuf+1, buf.c_str(), buf.size());
+ ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
// We can't use S->getSynchExpr()->getLocEnd() to find the end location, since
// the sync expression is typically a message expression that's already
// been rewritten! (which implies the SourceLocation's are invalid).
@@ -1578,7 +1595,7 @@ Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
buf += "id volatile _rethrow = 0;\n";
buf += "objc_exception_try_enter(&_stack);\n";
buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
- ReplaceText(rparenLoc, 1, buf.c_str(), buf.size());
+ ReplaceText(rparenLoc, 1, buf);
startLoc = S->getSynchBody()->getLocEnd();
startBuf = SM->getCharacterData(startLoc);
@@ -1607,7 +1624,7 @@ Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
buf += "}\n";
buf += "}";
- ReplaceText(lastCurlyLoc, 1, buf.c_str(), buf.size());
+ ReplaceText(lastCurlyLoc, 1, buf);
bool hasReturns = false;
HasReturnStmts(S->getSynchBody(), hasReturns);
@@ -1663,8 +1680,8 @@ void RewriteObjC::RewriteTryReturnStmts(Stmt *S) {
std::string buf;
buf = "{ objc_exception_try_exit(&_stack); return";
- ReplaceText(startLoc, 6, buf.c_str(), buf.size());
- InsertText(onePastSemiLoc, "}", 1);
+ ReplaceText(startLoc, 6, buf);
+ InsertText(onePastSemiLoc, "}");
}
return;
}
@@ -1689,8 +1706,8 @@ void RewriteObjC::RewriteSyncReturnStmts(Stmt *S, std::string syncExitBuf) {
buf += syncExitBuf;
buf += " return";
- ReplaceText(startLoc, 6, buf.c_str(), buf.size());
- InsertText(onePastSemiLoc, "}", 1);
+ ReplaceText(startLoc, 6, buf);
+ InsertText(onePastSemiLoc, "}");
}
return;
}
@@ -1711,7 +1728,7 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
buf += "objc_exception_try_enter(&_stack);\n";
buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
- ReplaceText(startLoc, 4, buf.c_str(), buf.size());
+ ReplaceText(startLoc, 4, buf);
startLoc = S->getTryBody()->getLocEnd();
startBuf = SM->getCharacterData(startLoc);
@@ -1729,12 +1746,12 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
buf += " _rethrow = objc_exception_extract(&_stack);\n";
buf += " else { /* @catch continue */";
- InsertText(startLoc, buf.c_str(), buf.size());
+ InsertText(startLoc, buf);
} else { /* no catch list */
buf = "}\nelse {\n";
buf += " _rethrow = objc_exception_extract(&_stack);\n";
buf += "}";
- ReplaceText(lastCurlyLoc, 1, buf.c_str(), buf.size());
+ ReplaceText(lastCurlyLoc, 1, buf);
}
bool sawIdTypedCatch = false;
Stmt *lastCatchBody = 0;
@@ -1767,7 +1784,7 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
QualType t = catchDecl->getType();
if (t == Context->getObjCIdType()) {
buf += "1) { ";
- ReplaceText(startLoc, lParenLoc-startBuf+1, buf.c_str(), buf.size());
+ ReplaceText(startLoc, lParenLoc-startBuf+1, buf);
sawIdTypedCatch = true;
} else if (t->isObjCObjectPointerType()) {
QualType InterfaceTy = t->getPointeeType();
@@ -1777,7 +1794,7 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
buf += "objc_exception_match((struct objc_class *)objc_getClass(\"";
buf += cls->getDecl()->getNameAsString();
buf += "\"), (struct objc_object *)_caught)) { ";
- ReplaceText(startLoc, lParenLoc-startBuf+1, buf.c_str(), buf.size());
+ ReplaceText(startLoc, lParenLoc-startBuf+1, buf);
}
}
// Now rewrite the body...
@@ -1789,10 +1806,9 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
assert((*rParenBuf == ')') && "bogus @catch paren location");
assert((*bodyBuf == '{') && "bogus @catch body location");
- buf = " = _caught;";
// Here we replace ") {" with "= _caught;" (which initializes and
// declares the @catch parameter).
- ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, buf.c_str(), buf.size());
+ ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, " = _caught;");
} else {
assert(false && "@catch rewrite bug");
}
@@ -1814,7 +1830,7 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
buf += "} } /* @catch end */\n";
if (!S->getFinallyStmt())
buf += "}\n";
- InsertText(bodyLoc, buf.c_str(), buf.size());
+ InsertText(bodyLoc, buf);
// Set lastCurlyLoc
lastCurlyLoc = lastCatchBody->getLocEnd();
@@ -1824,8 +1840,7 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
startBuf = SM->getCharacterData(startLoc);
assert((*startBuf == '@') && "bogus @finally start");
- buf = "/* @finally */";
- ReplaceText(startLoc, 8, buf.c_str(), buf.size());
+ ReplaceText(startLoc, 8, "/* @finally */");
Stmt *body = finalStmt->getFinallyBody();
SourceLocation startLoc = body->getLocStart();
@@ -1836,11 +1851,9 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
"bogus @finally body location");
startLoc = startLoc.getFileLocWithOffset(1);
- buf = " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
- InsertText(startLoc, buf.c_str(), buf.size());
+ InsertText(startLoc, " if (!_rethrow) objc_exception_try_exit(&_stack);\n");
endLoc = endLoc.getFileLocWithOffset(-1);
- buf = " if (_rethrow) objc_exception_throw(_rethrow);\n";
- InsertText(endLoc, buf.c_str(), buf.size());
+ InsertText(endLoc, " if (_rethrow) objc_exception_throw(_rethrow);\n");
// Set lastCurlyLoc
lastCurlyLoc = body->getLocEnd();
@@ -1852,7 +1865,7 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
buf += " if (_rethrow) objc_exception_throw(_rethrow);\n";
buf += "}";
- ReplaceText(lastCurlyLoc, 1, buf.c_str(), buf.size());
+ ReplaceText(lastCurlyLoc, 1, buf);
// Now check for any return/continue/go statements within the @try.
// The implicit finally clause won't called if the @try contains any
@@ -1864,8 +1877,7 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
}
// Now emit the final closing curly brace...
lastCurlyLoc = lastCurlyLoc.getFileLocWithOffset(1);
- buf = " } /* @try scope end */\n";
- InsertText(lastCurlyLoc, buf.c_str(), buf.size());
+ InsertText(lastCurlyLoc, " } /* @try scope end */\n");
return 0;
}
@@ -1897,13 +1909,12 @@ Stmt *RewriteObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) {
// handle "@ throw" correctly.
const char *wBuf = strchr(startBuf, 'w');
assert((*wBuf == 'w') && "@throw: can't find 'w'");
- ReplaceText(startLoc, wBuf-startBuf+1, buf.c_str(), buf.size());
+ ReplaceText(startLoc, wBuf-startBuf+1, buf);
const char *semiBuf = strchr(startBuf, ';');
assert((*semiBuf == ';') && "@throw: can't find ';'");
SourceLocation semiLoc = startLoc.getFileLocWithOffset(semiBuf-startBuf);
- buf = ");";
- ReplaceText(semiLoc, 1, buf.c_str(), buf.size());
+ ReplaceText(semiLoc, 1, ");");
return 0;
}
@@ -1991,7 +2002,17 @@ static void scanToNextArgument(const char *&argRef) {
}
bool RewriteObjC::needToScanForQualifiers(QualType T) {
- return T->isObjCQualifiedIdType() || T->isObjCQualifiedInterfaceType();
+ if (T->isObjCQualifiedIdType())
+ return true;
+ if (const PointerType *PT = T->getAs<PointerType>()) {
+ if (PT->getPointeeType()->isObjCQualifiedIdType())
+ return true;
+ }
+ if (T->isObjCObjectPointerType()) {
+ T = T->getPointeeType();
+ return T->isObjCQualifiedInterfaceType();
+ }
+ return false;
}
void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) {
@@ -2018,8 +2039,8 @@ void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) {
SourceLocation LessLoc = Loc.getFileLocWithOffset(startRef-startBuf);
SourceLocation GreaterLoc = Loc.getFileLocWithOffset(endRef-startBuf+1);
// Comment out the protocol references.
- InsertText(LessLoc, "/*", 2);
- InsertText(GreaterLoc, "*/", 2);
+ InsertText(LessLoc, "/*");
+ InsertText(GreaterLoc, "*/");
}
}
}
@@ -2063,8 +2084,8 @@ void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
SourceLocation LessLoc = Loc.getFileLocWithOffset(startRef-endBuf);
SourceLocation GreaterLoc = Loc.getFileLocWithOffset(endRef-endBuf+1);
// Comment out the protocol references.
- InsertText(LessLoc, "/*", 2);
- InsertText(GreaterLoc, "*/", 2);
+ InsertText(LessLoc, "/*");
+ InsertText(GreaterLoc, "*/");
}
}
if (!proto)
@@ -2087,8 +2108,8 @@ void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
SourceLocation GreaterLoc =
Loc.getFileLocWithOffset(endRef-startFuncBuf+1);
// Comment out the protocol references.
- InsertText(LessLoc, "/*", 2);
- InsertText(GreaterLoc, "*/", 2);
+ InsertText(LessLoc, "/*");
+ InsertText(GreaterLoc, "*/");
}
startBuf = ++endBuf;
}
@@ -2102,6 +2123,42 @@ void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
}
}
+void RewriteObjC::RewriteTypeOfDecl(VarDecl *ND) {
+ QualType QT = ND->getType();
+ const Type* TypePtr = QT->getAs<Type>();
+ if (!isa<TypeOfExprType>(TypePtr))
+ return;
+ while (isa<TypeOfExprType>(TypePtr)) {
+ const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
+ QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
+ TypePtr = QT->getAs<Type>();
+ }
+ // FIXME. This will not work for multiple declarators; as in:
+ // __typeof__(a) b,c,d;
+ std::string TypeAsString(QT.getAsString());
+ SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
+ const char *startBuf = SM->getCharacterData(DeclLoc);
+ if (ND->getInit()) {
+ std::string Name(ND->getNameAsString());
+ TypeAsString += " " + Name + " = ";
+ Expr *E = ND->getInit();
+ SourceLocation startLoc;
+ if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
+ startLoc = ECE->getLParenLoc();
+ else
+ startLoc = E->getLocStart();
+ startLoc = SM->getInstantiationLoc(startLoc);
+ const char *endBuf = SM->getCharacterData(startLoc);
+ ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
+ }
+ else {
+ SourceLocation X = ND->getLocEnd();
+ X = SM->getInstantiationLoc(X);
+ const char *endBuf = SM->getCharacterData(X);
+ ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
+ }
+}
+
// SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str);
void RewriteObjC::SynthSelGetUidFunctionDecl() {
IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName");
@@ -2126,6 +2183,19 @@ void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) {
RewriteObjCQualifiedInterfaceTypes(FD);
}
+static void RewriteBlockPointerType(std::string& Str, QualType Type) {
+ std::string TypeString(Type.getAsString());
+ const char *argPtr = TypeString.c_str();
+ if (!strchr(argPtr, '^')) {
+ Str += TypeString;
+ return;
+ }
+ while (*argPtr) {
+ Str += (*argPtr == '^' ? '*' : *argPtr);
+ argPtr++;
+ }
+}
+
void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) {
SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
@@ -2140,13 +2210,12 @@ void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) {
unsigned numArgs = proto->getNumArgs();
for (unsigned i = 0; i < numArgs; i++) {
QualType ArgType = proto->getArgType(i);
- FdStr += ArgType.getAsString();
-
+ RewriteBlockPointerType(FdStr, ArgType);
if (i+1 < numArgs)
FdStr += ", ";
}
FdStr += ");\n";
- InsertText(FunLocStart, FdStr.c_str(), FdStr.size());
+ InsertText(FunLocStart, FdStr);
CurFunctionDeclToDeclareForBlock = 0;
}
@@ -2330,7 +2399,7 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
Preamble += utostr(Exp->getString()->getByteLength()) + "};\n";
VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
- &Context->Idents.get(S.c_str()), strType, 0,
+ &Context->Idents.get(S), strType, 0,
VarDecl::Static);
DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, strType, SourceLocation());
Expr *Unop = new (Context) UnaryOperator(DRE, UnaryOperator::AddrOf,
@@ -2380,7 +2449,7 @@ QualType RewriteObjC::getSuperStructType() {
/*Mutable=*/false));
}
- SuperStructDecl->completeDefinition(*Context);
+ SuperStructDecl->completeDefinition();
}
return Context->getTagDeclType(SuperStructDecl);
}
@@ -2411,7 +2480,7 @@ QualType RewriteObjC::getConstantStringStructType() {
/*Mutable=*/true));
}
- ConstantStringDecl->completeDefinition(*Context);
+ ConstantStringDecl->completeDefinition();
}
return Context->getTagDeclType(ConstantStringDecl);
}
@@ -2871,7 +2940,7 @@ void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
if ((CDecl->isForwardDecl() || NumIvars == 0) &&
(!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
- ReplaceText(LocStart, endBuf-startBuf, Result.c_str(), Result.size());
+ ReplaceText(LocStart, endBuf-startBuf, Result);
return;
}
@@ -2913,10 +2982,10 @@ void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
endHeader++;
}
// rewrite the original header
- ReplaceText(LocStart, endHeader-startBuf, Result.c_str(), Result.size());
+ ReplaceText(LocStart, endHeader-startBuf, Result);
} else {
// rewrite the original header *without* disturbing the '{'
- ReplaceText(LocStart, cursor-startBuf, Result.c_str(), Result.size());
+ ReplaceText(LocStart, cursor-startBuf, Result);
}
if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
Result = "\n struct ";
@@ -2928,7 +2997,7 @@ void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
// insert the super class structure definition.
SourceLocation OnePastCurly =
LocStart.getFileLocWithOffset(cursor-startBuf+1);
- InsertText(OnePastCurly, Result.c_str(), Result.size());
+ InsertText(OnePastCurly, Result);
}
cursor++; // past '{'
@@ -2946,26 +3015,26 @@ void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
!strncmp(cursor, "private", strlen("private")) ||
!strncmp(cursor, "package", strlen("package")) ||
!strncmp(cursor, "protected", strlen("protected")))
- InsertText(atLoc, "// ", 3);
+ InsertText(atLoc, "// ");
}
// FIXME: If there are cases where '<' is used in ivar declaration part
// of user code, then scan the ivar list and use needToScanForQualifiers
// for type checking.
else if (*cursor == '<') {
SourceLocation atLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
- InsertText(atLoc, "/* ", 3);
+ InsertText(atLoc, "/* ");
cursor = strchr(cursor, '>');
cursor++;
atLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
- InsertText(atLoc, " */", 3);
+ InsertText(atLoc, " */");
} else if (*cursor == '^') { // rewrite block specifier.
SourceLocation caretLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
- ReplaceText(caretLoc, 1, "*", 1);
+ ReplaceText(caretLoc, 1, "*");
}
cursor++;
}
// Don't forget to add a ';'!!
- InsertText(LocEnd.getFileLocWithOffset(1), ";", 1);
+ InsertText(LocEnd.getFileLocWithOffset(1), ";");
} else { // we don't have any instance variables - insert super struct.
endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
Result += " {\n struct ";
@@ -2973,7 +3042,7 @@ void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
Result += "_IMPL ";
Result += RCDecl->getNameAsString();
Result += "_IVARS;\n};\n";
- ReplaceText(LocStart, endBuf-startBuf, Result.c_str(), Result.size());
+ ReplaceText(LocStart, endBuf-startBuf, Result);
}
// Mark this struct as having been generated.
if (!ObjCSynthesizedStructs.insert(CDecl))
@@ -3805,7 +3874,7 @@ std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
// Create local declarations to avoid rewriting all closure decl ref exprs.
// First, emit a declaration for all "by ref" decls.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
+ for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
E = BlockByRefDecls.end(); I != E; ++I) {
S += " ";
std::string Name = (*I)->getNameAsString();
@@ -3816,7 +3885,7 @@ std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n";
}
// Next, emit a declaration for all "by copy" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
+ for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
E = BlockByCopyDecls.end(); I != E; ++I) {
S += " ";
std::string Name = (*I)->getNameAsString();
@@ -3861,7 +3930,7 @@ std::string RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
S += (*I)->getNameAsString();
S += ", (void*)src->";
S += (*I)->getNameAsString();
- if (BlockByRefDecls.count((*I)))
+ if (BlockByRefDeclsPtrSet.count((*I)))
S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
else
S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
@@ -3877,7 +3946,7 @@ std::string RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
E = ImportedBlockDecls.end(); I != E; ++I) {
S += "_Block_object_dispose((void*)src->";
S += (*I)->getNameAsString();
- if (BlockByRefDecls.count((*I)))
+ if (BlockByRefDeclsPtrSet.count((*I)))
S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
else
S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
@@ -3901,7 +3970,7 @@ std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
if (BlockDeclRefs.size()) {
// Output all "by copy" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
+ for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
E = BlockByCopyDecls.end(); I != E; ++I) {
S += " ";
std::string FieldName = (*I)->getNameAsString();
@@ -3927,7 +3996,7 @@ std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
S += FieldName + ";\n";
}
// Output all "by ref" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
+ for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
E = BlockByRefDecls.end(); I != E; ++I) {
S += " ";
std::string FieldName = (*I)->getNameAsString();
@@ -3966,7 +4035,7 @@ std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
Constructor += " Desc = desc;\n";
// Initialize all "by copy" arguments.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
+ for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
E = BlockByCopyDecls.end(); I != E; ++I) {
std::string Name = (*I)->getNameAsString();
Constructor += " ";
@@ -3977,7 +4046,7 @@ std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
Constructor += Name + ";\n";
}
// Initialize all "by ref" arguments.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
+ for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
E = BlockByRefDecls.end(); I != E; ++I) {
std::string Name = (*I)->getNameAsString();
Constructor += " ";
@@ -4047,23 +4116,25 @@ void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
- InsertText(FunLocStart, CI.c_str(), CI.size());
+ InsertText(FunLocStart, CI);
std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
- InsertText(FunLocStart, CF.c_str(), CF.size());
+ InsertText(FunLocStart, CF);
if (ImportedBlockDecls.size()) {
std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
- InsertText(FunLocStart, HF.c_str(), HF.size());
+ InsertText(FunLocStart, HF);
}
std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
ImportedBlockDecls.size() > 0);
- InsertText(FunLocStart, BD.c_str(), BD.size());
+ InsertText(FunLocStart, BD);
BlockDeclRefs.clear();
BlockByRefDecls.clear();
+ BlockByRefDeclsPtrSet.clear();
BlockByCopyDecls.clear();
+ BlockByCopyDeclsPtrSet.clear();
BlockCallExprs.clear();
ImportedBlockDecls.clear();
}
@@ -4078,17 +4149,23 @@ void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
SynthesizeBlockLiterals(FunLocStart, FuncName);
}
-void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {
- //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n");
- //SourceLocation FunLocStart = MD->getLocStart();
- // FIXME: This hack works around a bug in Rewrite.InsertText().
- SourceLocation FunLocStart = MD->getLocStart().getFileLocWithOffset(-1);
- std::string FuncName = MD->getSelector().getAsString();
+static void BuildUniqueMethodName(std::string &Name,
+ ObjCMethodDecl *MD) {
+ ObjCInterfaceDecl *IFace = MD->getClassInterface();
+ Name = IFace->getNameAsCString();
+ Name += "__" + MD->getSelector().getAsString();
// Convert colons to underscores.
std::string::size_type loc = 0;
- while ((loc = FuncName.find(":", loc)) != std::string::npos)
- FuncName.replace(loc, 1, "_");
+ while ((loc = Name.find(":", loc)) != std::string::npos)
+ Name.replace(loc, 1, "_");
+}
+void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {
+ //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n");
+ //SourceLocation FunLocStart = MD->getLocStart();
+ SourceLocation FunLocStart = MD->getLocStart();
+ std::string FuncName;
+ BuildUniqueMethodName(FuncName, MD);
SynthesizeBlockLiterals(FunLocStart, FuncName.c_str());
}
@@ -4304,11 +4381,9 @@ void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) {
std::string TypeAsString = "(";
TypeAsString += QT.getAsString();
TypeAsString += ")";
- ReplaceText(LocStart, endBuf-startBuf+1,
- TypeAsString.c_str(), TypeAsString.size());
+ ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
return;
}
-
// advance the location to startArgList.
const char *argPtr = startBuf;
@@ -4317,7 +4392,7 @@ void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) {
case '^':
// Replace the '^' with '*'.
LocStart = LocStart.getFileLocWithOffset(argPtr-startBuf);
- ReplaceText(LocStart, 1, "*", 1);
+ ReplaceText(LocStart, 1, "*");
break;
}
}
@@ -4346,7 +4421,7 @@ void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
case '^':
// Replace the '^' with '*'.
DeclLoc = DeclLoc.getFileLocWithOffset(argPtr-startArgList);
- ReplaceText(DeclLoc, 1, "*", 1);
+ ReplaceText(DeclLoc, 1, "*");
break;
case '(':
parenCount++;
@@ -4427,7 +4502,7 @@ void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) {
if (*startBuf == '^') {
// Replace the '^' with '*', computing a negative offset.
DeclLoc = DeclLoc.getFileLocWithOffset(startBuf-endBuf);
- ReplaceText(DeclLoc, 1, "*", 1);
+ ReplaceText(DeclLoc, 1, "*");
}
if (PointerTypeTakesAnyBlockArguments(DeclT)) {
// Replace the '^' with '*' for arguments.
@@ -4438,7 +4513,7 @@ void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) {
while (argListBegin < argListEnd) {
if (*argListBegin == '^') {
SourceLocation CaretLoc = DeclLoc.getFileLocWithOffset(argListBegin-startBuf);
- ReplaceText(CaretLoc, 1, "*", 1);
+ ReplaceText(CaretLoc, 1, "*");
}
argListBegin++;
}
@@ -4563,7 +4638,7 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null");
FunLocStart = CurMethodDef->getLocStart();
}
- InsertText(FunLocStart, ByrefType.c_str(), ByrefType.size());
+ InsertText(FunLocStart, ByrefType);
if (Ty.isObjCGCWeak()) {
flag |= BLOCK_FIELD_IS_WEAK;
isa = 1;
@@ -4579,7 +4654,7 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
flag |= BLOCK_FIELD_IS_OBJECT;
std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
if (!HF.empty())
- InsertText(FunLocStart, HF.c_str(), HF.size());
+ InsertText(FunLocStart, HF);
}
// struct __Block_byref_ND ND =
@@ -4592,10 +4667,12 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
Name = ND->getNameAsString();
ByrefType.clear();
RewriteByRefString(ByrefType, Name, ND);
+ std::string ForwardingCastType("(");
+ ForwardingCastType += ByrefType + " *)";
if (!hasInit) {
ByrefType += " " + Name + " = {(void*)";
ByrefType += utostr(isa);
- ByrefType += ", &" + Name + ", ";
+ ByrefType += "," + ForwardingCastType + "&" + Name + ", ";
ByrefType += utostr(flags);
ByrefType += ", ";
ByrefType += "sizeof(";
@@ -4608,8 +4685,7 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
ByrefType += utostr(flag);
}
ByrefType += "};\n";
- ReplaceText(DeclLoc, endBuf-startBuf+Name.size(),
- ByrefType.c_str(), ByrefType.size());
+ ReplaceText(DeclLoc, endBuf-startBuf+Name.size(), ByrefType);
}
else {
SourceLocation startLoc;
@@ -4624,7 +4700,7 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
ByrefType += " " + Name;
ByrefType += " = {(void*)";
ByrefType += utostr(isa);
- ByrefType += ", &" + Name + ", ";
+ ByrefType += "," + ForwardingCastType + "&" + Name + ", ";
ByrefType += utostr(flags);
ByrefType += ", ";
ByrefType += "sizeof(";
@@ -4637,8 +4713,7 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
ByrefType += utostr(flag);
ByrefType += ", ";
}
- ReplaceText(DeclLoc, endBuf-startBuf,
- ByrefType.c_str(), ByrefType.size());
+ ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
// Complete the newly synthesized compound expression by inserting a right
// curly brace before the end of the declaration.
@@ -4654,7 +4729,7 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
SourceLocation semiLoc =
startLoc.getFileLocWithOffset(semiBuf-startBuf);
- InsertText(semiLoc, "}", 1);
+ InsertText(semiLoc, "}");
}
return;
}
@@ -4665,12 +4740,19 @@ void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) {
if (BlockDeclRefs.size()) {
// Unique all "by copy" declarations.
for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
- if (!BlockDeclRefs[i]->isByRef())
- BlockByCopyDecls.insert(BlockDeclRefs[i]->getDecl());
+ if (!BlockDeclRefs[i]->isByRef()) {
+ if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
+ BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
+ BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
+ }
+ }
// Unique all "by ref" declarations.
for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
if (BlockDeclRefs[i]->isByRef()) {
- BlockByRefDecls.insert(BlockDeclRefs[i]->getDecl());
+ if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
+ BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
+ BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
+ }
}
// Find any imported blocks...they will need special attention.
for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
@@ -4699,13 +4781,9 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp) {
if (CurFunctionDef)
FuncName = CurFunctionDef->getNameAsString();
- else if (CurMethodDef) {
- FuncName = CurMethodDef->getSelector().getAsString();
- // Convert colons to underscores.
- std::string::size_type loc = 0;
- while ((loc = FuncName.find(":", loc)) != std::string::npos)
- FuncName.replace(loc, 1, "_");
- } else if (GlobalVarDecl)
+ else if (CurMethodDef)
+ BuildUniqueMethodName(FuncName, CurMethodDef);
+ else if (GlobalVarDecl)
FuncName = std::string(GlobalVarDecl->getNameAsString());
std::string BlockNumber = utostr(Blocks.size()-1);
@@ -4752,7 +4830,7 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp) {
if (BlockDeclRefs.size()) {
Expr *Exp;
// Output all "by copy" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
+ for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
E = BlockByCopyDecls.end(); I != E; ++I) {
if (isObjCType((*I)->getType())) {
// FIXME: Conform to ABI ([[obj retain] autorelease]).
@@ -4770,13 +4848,25 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp) {
InitExprs.push_back(Exp);
}
// Output all "by ref" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
+ for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
E = BlockByRefDecls.end(); I != E; ++I) {
+ ValueDecl *ND = (*I);
+ std::string Name(ND->getNameAsString());
+ std::string RecName;
+ RewriteByRefString(RecName, Name, ND);
+ IdentifierInfo *II = &Context->Idents.get(RecName.c_str()
+ + sizeof("struct"));
+ RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+ SourceLocation(), II);
+ assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl");
+ QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+
FD = SynthBlockInitFunctionDecl((*I)->getNameAsCString());
Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
Exp = new (Context) UnaryOperator(Exp, UnaryOperator::AddrOf,
Context->getPointerType(Exp->getType()),
SourceLocation());
+ Exp = NoTypeInfoCStyleCastExpr(Context, castT, CastExpr::CK_Unknown, Exp);
InitExprs.push_back(Exp);
}
}
@@ -4798,7 +4888,9 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp) {
NewRep);
BlockDeclRefs.clear();
BlockByRefDecls.clear();
+ BlockByRefDeclsPtrSet.clear();
BlockByCopyDecls.clear();
+ BlockByCopyDeclsPtrSet.clear();
ImportedBlockDecls.clear();
return NewRep;
}
@@ -4843,7 +4935,21 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
CI != E; ++CI)
if (*CI) {
- Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(*CI);
+ Stmt *newStmt;
+ Stmt *S = (*CI);
+ if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
+ Expr *OldBase = IvarRefExpr->getBase();
+ bool replaced = false;
+ newStmt = RewriteObjCNestedIvarRefExpr(S, replaced);
+ if (replaced) {
+ if (ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(newStmt))
+ ReplaceStmt(OldBase, IRE->getBase());
+ else
+ ReplaceStmt(S, newStmt);
+ }
+ }
+ else
+ newStmt = RewriteFunctionBodyOrGlobalInitializer(S);
if (newStmt)
*CI = newStmt;
}
@@ -4865,9 +4971,6 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
return RewriteAtEncode(AtEncode);
- if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S))
- return RewriteObjCIvarRefExpr(IvarRefExpr, OrigStmtRange.getBegin());
-
if (ObjCPropertyRefExpr *PropRefExpr = dyn_cast<ObjCPropertyRefExpr>(S)) {
BinaryOperator *BinOp = PropSetters[PropRefExpr];
if (BinOp) {
@@ -4995,7 +5098,7 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
RewriteBlockPointerDecl(ND);
else if (ND->getType()->isFunctionPointerType())
CheckFunctionPointerDecl(ND->getType(), ND);
- if (VarDecl *VD = dyn_cast<VarDecl>(SD))
+ if (VarDecl *VD = dyn_cast<VarDecl>(SD)) {
if (VD->hasAttr<BlocksAttr>()) {
static unsigned uniqueByrefDeclCount = 0;
assert(!BlockByRefDeclNo.count(ND) &&
@@ -5003,6 +5106,9 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
RewriteByRefVar(VD);
}
+ else
+ RewriteTypeOfDecl(VD);
+ }
}
if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
@@ -5191,11 +5297,6 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) {
}
void RewriteObjC::HandleTranslationUnit(ASTContext &C) {
- // Get the top-level buffer that this corresponds to.
-
- // Rewrite tabs if we care.
- //RewriteTabs();
-
if (Diags.hasErrorOccurred())
return;
@@ -5207,8 +5308,7 @@ void RewriteObjC::HandleTranslationUnit(ASTContext &C) {
E = ProtocolExprDecls.end(); I != E; ++I)
RewriteObjCProtocolMetaData(*I, "", "", Preamble);
- InsertText(SM->getLocForStartOfFile(MainFileID),
- Preamble.c_str(), Preamble.size(), false);
+ InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false);
if (ClassImplementation.size() || CategoryImplementation.size())
RewriteImplementations();
@@ -5219,7 +5319,7 @@ void RewriteObjC::HandleTranslationUnit(ASTContext &C) {
//printf("Changed:\n");
*OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
} else {
- fprintf(stderr, "No changes\n");
+ llvm::errs() << "No changes\n";
}
if (ClassImplementation.size() || CategoryImplementation.size() ||
OpenPOWER on IntegriCloud