diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Rewrite')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Rewrite/RewriteObjC.cpp | 160 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Rewrite/Rewriter.cpp | 177 |
2 files changed, 260 insertions, 77 deletions
diff --git a/contrib/llvm/tools/clang/lib/Rewrite/RewriteObjC.cpp b/contrib/llvm/tools/clang/lib/Rewrite/RewriteObjC.cpp index 0263f65..d6e34ef 100644 --- a/contrib/llvm/tools/clang/lib/Rewrite/RewriteObjC.cpp +++ b/contrib/llvm/tools/clang/lib/Rewrite/RewriteObjC.cpp @@ -1426,7 +1426,8 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, RecName += "_IMPL"; IdentifierInfo *II = &Context->Idents.get(RecName); RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, - SourceLocation(), II); + SourceLocation(), SourceLocation(), + II); assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl"); QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT, @@ -1472,7 +1473,8 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, RecName += "_IMPL"; IdentifierInfo *II = &Context->Idents.get(RecName); RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, - SourceLocation(), II); + SourceLocation(), SourceLocation(), + II); assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl"); QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT, @@ -2109,7 +2111,8 @@ Stmt *RewriteObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) { std::string StrEncoding; Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding); Expr *Replacement = StringLiteral::Create(*Context,StrEncoding.c_str(), - StrEncoding.length(), false,StrType, + StrEncoding.length(), + false, false, StrType, SourceLocation()); ReplaceStmt(Exp, Replacement); @@ -2128,7 +2131,8 @@ Stmt *RewriteObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) { SelExprs.push_back(StringLiteral::Create(*Context, Exp->getSelector().getAsString().c_str(), Exp->getSelector().getAsString().size(), - false, argType, SourceLocation())); + false, false, argType, + SourceLocation())); CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, &SelExprs[0], SelExprs.size()); ReplaceStmt(Exp, SelExp); @@ -2361,6 +2365,7 @@ void RewriteObjC::SynthSelGetUidFunctionDecl() { getSimpleFunctionType(Context->getObjCSelType(), &ArgTys[0], ArgTys.size()); SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), + SourceLocation(), SelGetUidIdent, getFuncType, 0, SC_Extern, SC_None, false); @@ -2457,6 +2462,7 @@ void RewriteObjC::SynthSuperContructorFunctionDecl() { &ArgTys[0], ArgTys.size()); SuperContructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), + SourceLocation(), msgSendIdent, msgSendType, 0, SC_Extern, SC_None, false); @@ -2477,6 +2483,7 @@ void RewriteObjC::SynthMsgSendFunctionDecl() { true /*isVariadic*/); MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), + SourceLocation(), msgSendIdent, msgSendType, 0, SC_Extern, SC_None, false); @@ -2487,7 +2494,7 @@ void RewriteObjC::SynthMsgSendSuperFunctionDecl() { IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper"); llvm::SmallVector<QualType, 16> ArgTys; RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, - SourceLocation(), + SourceLocation(), SourceLocation(), &Context->Idents.get("objc_super")); QualType argT = Context->getPointerType(Context->getTagDeclType(RD)); assert(!argT.isNull() && "Can't build 'struct objc_super *' type"); @@ -2500,6 +2507,7 @@ void RewriteObjC::SynthMsgSendSuperFunctionDecl() { true /*isVariadic*/); MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), + SourceLocation(), msgSendIdent, msgSendType, 0, SC_Extern, SC_None, false); @@ -2520,6 +2528,7 @@ void RewriteObjC::SynthMsgSendStretFunctionDecl() { true /*isVariadic*/); MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), + SourceLocation(), msgSendIdent, msgSendType, 0, SC_Extern, SC_None, false); @@ -2532,7 +2541,7 @@ void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() { &Context->Idents.get("objc_msgSendSuper_stret"); llvm::SmallVector<QualType, 16> ArgTys; RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, - SourceLocation(), + SourceLocation(), SourceLocation(), &Context->Idents.get("objc_super")); QualType argT = Context->getPointerType(Context->getTagDeclType(RD)); assert(!argT.isNull() && "Can't build 'struct objc_super *' type"); @@ -2545,6 +2554,7 @@ void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() { true /*isVariadic*/); MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), + SourceLocation(), msgSendIdent, msgSendType, 0, SC_Extern, SC_None, false); @@ -2565,6 +2575,7 @@ void RewriteObjC::SynthMsgSendFpretFunctionDecl() { true /*isVariadic*/); MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), + SourceLocation(), msgSendIdent, msgSendType, 0, SC_Extern, SC_None, false); @@ -2579,6 +2590,7 @@ void RewriteObjC::SynthGetClassFunctionDecl() { &ArgTys[0], ArgTys.size()); GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), + SourceLocation(), getClassIdent, getClassType, 0, SC_Extern, SC_None, false); @@ -2594,6 +2606,7 @@ void RewriteObjC::SynthGetSuperClassFunctionDecl() { &ArgTys[0], ArgTys.size()); GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), + SourceLocation(), getSuperClassIdent, getClassType, 0, SC_Extern, @@ -2610,6 +2623,7 @@ void RewriteObjC::SynthGetMetaClassFunctionDecl() { &ArgTys[0], ArgTys.size()); GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), + SourceLocation(), getClassIdent, getClassType, 0, SC_Extern, SC_None, false); @@ -2645,8 +2659,8 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { Preamble += utostr(Exp->getString()->getByteLength()) + "};\n"; VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), - &Context->Idents.get(S), strType, 0, - SC_Static, SC_None); + SourceLocation(), &Context->Idents.get(S), + strType, 0, SC_Static, SC_None); DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, strType, VK_LValue, SourceLocation()); Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf, @@ -2665,7 +2679,7 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { QualType RewriteObjC::getSuperStructType() { if (!SuperStructDecl) { SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl, - SourceLocation(), + SourceLocation(), SourceLocation(), &Context->Idents.get("objc_super")); QualType FieldTypes[2]; @@ -2677,6 +2691,7 @@ QualType RewriteObjC::getSuperStructType() { // Create fields for (unsigned i = 0; i < 2; ++i) { SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl, + SourceLocation(), SourceLocation(), 0, FieldTypes[i], 0, /*BitWidth=*/0, @@ -2691,7 +2706,7 @@ QualType RewriteObjC::getSuperStructType() { QualType RewriteObjC::getConstantStringStructType() { if (!ConstantStringDecl) { ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl, - SourceLocation(), + SourceLocation(), SourceLocation(), &Context->Idents.get("__NSConstantStringImpl")); QualType FieldTypes[4]; @@ -2708,6 +2723,7 @@ QualType RewriteObjC::getConstantStringStructType() { for (unsigned i = 0; i < 4; ++i) { ConstantStringDecl->addDecl(FieldDecl::Create(*Context, ConstantStringDecl, + SourceLocation(), SourceLocation(), 0, FieldTypes[i], 0, /*BitWidth=*/0, @@ -2782,7 +2798,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, ClsExprs.push_back(StringLiteral::Create(*Context, ClassDecl->getIdentifier()->getNameStart(), ClassDecl->getIdentifier()->getLength(), - false, argType, SourceLocation())); + false, false, argType, SourceLocation())); CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl, &ClsExprs[0], ClsExprs.size(), @@ -2861,8 +2877,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, ClsExprs.push_back(StringLiteral::Create(*Context, clsName->getNameStart(), clsName->getLength(), - false, argType, - SourceLocation())); + false, false, + argType, SourceLocation())); CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, &ClsExprs[0], ClsExprs.size(), @@ -2893,7 +2909,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, ClsExprs.push_back(StringLiteral::Create(*Context, ClassDecl->getIdentifier()->getNameStart(), ClassDecl->getIdentifier()->getLength(), - false, argType, SourceLocation())); + false, false, argType, SourceLocation())); CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, &ClsExprs[0], ClsExprs.size(), @@ -2975,7 +2991,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, SelExprs.push_back(StringLiteral::Create(*Context, Exp->getSelector().getAsString().c_str(), Exp->getSelector().getAsString().size(), - false, argType, SourceLocation())); + false, false, argType, SourceLocation())); CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl, &SelExprs[0], SelExprs.size(), StartLoc, @@ -3102,10 +3118,11 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, SourceLocation()); // Build sizeof(returnType) - SizeOfAlignOfExpr *sizeofExpr = new (Context) SizeOfAlignOfExpr(true, - Context->getTrivialTypeSourceInfo(returnType), - Context->getSizeType(), - SourceLocation(), SourceLocation()); + UnaryExprOrTypeTraitExpr *sizeofExpr = + new (Context) UnaryExprOrTypeTraitExpr(UETT_SizeOf, + Context->getTrivialTypeSourceInfo(returnType), + Context->getSizeType(), SourceLocation(), + SourceLocation()); // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...)) // FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases. // For X86 it is more complicated and some kind of target specific routine @@ -3149,7 +3166,7 @@ QualType RewriteObjC::getProtocolType() { TypeSourceInfo *TInfo = Context->getTrivialTypeSourceInfo(Context->getObjCIdType()); ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl, - SourceLocation(), + SourceLocation(), SourceLocation(), &Context->Idents.get("Protocol"), TInfo); } @@ -3164,7 +3181,7 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString(); IdentifierInfo *ID = &Context->Idents.get(Name); VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(), - ID, getProtocolType(), 0, + SourceLocation(), ID, getProtocolType(), 0, SC_Extern, SC_None); DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), VK_LValue, SourceLocation()); @@ -3745,7 +3762,7 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl, std::string &Result) { ObjCInterfaceDecl *CDecl = IDecl->getClassInterface(); - // Explictly declared @interface's are already synthesized. + // Explicitly declared @interface's are already synthesized. if (CDecl->isImplicitInterfaceDecl()) { // FIXME: Implementation of a class with no @interface (legacy) doese not // produce correct synthesis as yet. @@ -4315,20 +4332,7 @@ std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, S += " "; std::string FieldName = (*I)->getNameAsString(); std::string ArgName = "_" + FieldName; - // Handle nested closure invocation. For example: - // - // void (^myImportedBlock)(void); - // myImportedBlock = ^(void) { setGlobalInt(x + y); }; - // - // void (^anotherBlock)(void); - // anotherBlock = ^(void) { - // myImportedBlock(); // import and invoke the closure - // }; - // - if (isTopLevelBlockPointerType((*I)->getType())) { - S += "struct __block_impl *"; - Constructor += ", void *" + ArgName; - } else { + { std::string TypeString; RewriteByRefString(TypeString, FieldName, (*I)); TypeString += " *"; @@ -4366,11 +4370,7 @@ std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, } else Constructor += ", "; - if (isTopLevelBlockPointerType((*I)->getType())) - Constructor += Name + "((struct __block_impl *)_" - + Name + "->__forwarding)"; - else - Constructor += Name + "(_" + Name + "->__forwarding)"; + Constructor += Name + "(_" + Name + "->__forwarding)"; } Constructor += " {\n"; @@ -4601,7 +4601,7 @@ void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S, /// convertFunctionTypeOfBlocks - This routine converts a function type /// whose result type may be a block pointer or whose argument type(s) -/// might be block pointers to an equivalent funtion type replacing +/// might be block pointers to an equivalent function type replacing /// all block pointers to function pointers. QualType RewriteObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) { const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT); @@ -4672,7 +4672,7 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { // FTP will be null for closures that don't take arguments. RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, - SourceLocation(), + SourceLocation(), SourceLocation(), &Context->Idents.get("__block_impl")); QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD)); @@ -4706,7 +4706,9 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { //PE->dump(); FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(), - &Context->Idents.get("FuncPtr"), Context->VoidPtrTy, 0, + SourceLocation(), + &Context->Idents.get("FuncPtr"), + Context->VoidPtrTy, 0, /*BitWidth=*/0, /*Mutable=*/true); MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(), FD->getType(), VK_LValue, @@ -4758,6 +4760,7 @@ Stmt *RewriteObjC::RewriteBlockDeclRefExpr(Expr *DeclRefExp) { } FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(), + SourceLocation(), &Context->Idents.get("__forwarding"), Context->VoidPtrTy, 0, /*BitWidth=*/0, /*Mutable=*/true); @@ -4767,7 +4770,7 @@ Stmt *RewriteObjC::RewriteBlockDeclRefExpr(Expr *DeclRefExp) { OK_Ordinary); llvm::StringRef Name = VD->getName(); - FD = FieldDecl::Create(*Context, 0, SourceLocation(), + FD = FieldDecl::Create(*Context, 0, SourceLocation(), SourceLocation(), &Context->Idents.get(Name), Context->VoidPtrTy, 0, /*BitWidth=*/0, /*Mutable=*/true); @@ -4777,7 +4780,8 @@ Stmt *RewriteObjC::RewriteBlockDeclRefExpr(Expr *DeclRefExp) { // Need parens to enforce precedence. - ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), + ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), + DeclRefExp->getExprLoc(), ME); ReplaceStmt(DeclRefExp, PE); return PE; @@ -4949,7 +4953,7 @@ void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) { QualType DeclT; if (VarDecl *VD = dyn_cast<VarDecl>(ND)) DeclT = VD->getType(); - else if (TypedefDecl *TDD = dyn_cast<TypedefDecl>(ND)) + else if (TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(ND)) DeclT = TDD->getUnderlyingType(); else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND)) DeclT = FD->getType(); @@ -5053,7 +5057,7 @@ std::string RewriteObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD, unsigned VoidPtrSize = static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy)); - unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/8; + unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth(); S += " _Block_object_assign((char*)dst + "; S += utostr(offset); S += ", *(void * *) ((char*)src + "; @@ -5124,8 +5128,11 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) { ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n"; ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n"; } - - Ty.getAsStringInternal(Name, Context->PrintingPolicy); + + QualType T = Ty; + (void)convertBlockPointerToFunctionPointer(T); + T.getAsStringInternal(Name, Context->PrintingPolicy); + ByrefType += " " + Name + ";\n"; ByrefType += "};\n"; // Insert this type in global scope. It is needed by helper function. @@ -5183,7 +5190,12 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) { ByrefType += utostr(flag); } ByrefType += "};\n"; - ReplaceText(DeclLoc, endBuf-startBuf+Name.size(), ByrefType); + unsigned nameSize = Name.size(); + // for block or function pointer declaration. Name is aleady + // part of the declaration. + if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) + nameSize = 1; + ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType); } else { SourceLocation startLoc; @@ -5263,8 +5275,8 @@ void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) { FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(llvm::StringRef name) { IdentifierInfo *ID = &Context->Idents.get(name); QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy); - return FunctionDecl::Create(*Context, TUDecl,SourceLocation(), - ID, FType, 0, SC_Extern, + return FunctionDecl::Create(*Context, TUDecl, SourceLocation(), + SourceLocation(), ID, FType, 0, SC_Extern, SC_None, false, false); } @@ -5345,10 +5357,11 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, // Initialize the block descriptor. std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA"; - VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), - &Context->Idents.get(DescData.c_str()), - Context->VoidPtrTy, 0, - SC_Static, SC_None); + VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, + SourceLocation(), SourceLocation(), + &Context->Idents.get(DescData.c_str()), + Context->VoidPtrTy, 0, + SC_Static, SC_None); UnaryOperator *DescRefExpr = new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, Context->VoidPtrTy, @@ -5407,7 +5420,8 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, IdentifierInfo *II = &Context->Idents.get(RecName.c_str() + sizeof("struct")); RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl, - SourceLocation(), II); + SourceLocation(), SourceLocation(), + II); assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl"); QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); @@ -5507,27 +5521,34 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { for (Stmt::child_range CI = S->children(); CI; ++CI) if (*CI) { Stmt *newStmt; - Stmt *S = (*CI); - if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) { + Stmt *ChildStmt = (*CI); + if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(ChildStmt)) { Expr *OldBase = IvarRefExpr->getBase(); bool replaced = false; - newStmt = RewriteObjCNestedIvarRefExpr(S, replaced); + newStmt = RewriteObjCNestedIvarRefExpr(ChildStmt, replaced); if (replaced) { if (ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(newStmt)) ReplaceStmt(OldBase, IRE->getBase()); else - ReplaceStmt(S, newStmt); + ReplaceStmt(ChildStmt, newStmt); } } else - newStmt = RewriteFunctionBodyOrGlobalInitializer(S); - if (newStmt) - *CI = newStmt; + newStmt = RewriteFunctionBodyOrGlobalInitializer(ChildStmt); + if (newStmt) { + if (Expr *PropOrImplicitRefExpr = dyn_cast<Expr>(ChildStmt)) + if (PropSetters[PropOrImplicitRefExpr] == S) { + S = newStmt; + newStmt = 0; + } + if (newStmt) + *CI = newStmt; + } // If dealing with an assignment with LHS being a property reference // expression, the entire assignment tree is rewritten into a property // setter messaging. This involvs the RHS too. Do not attempt to rewrite // RHS again. - if (Expr *Exp = dyn_cast<Expr>(S)) + if (Expr *Exp = dyn_cast<Expr>(ChildStmt)) if (isa<ObjCPropertyRefExpr>(Exp)) { if (PropSetters[Exp]) { ++CI; @@ -5546,13 +5567,14 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { // Rewrite the block body in place. Stmt *SaveCurrentBody = CurrentBody; CurrentBody = BE->getBody(); + CollectPropertySetters(CurrentBody); PropParentMap = 0; RewriteFunctionBodyOrGlobalInitializer(BE->getBody()); CurrentBody = SaveCurrentBody; PropParentMap = 0; ImportedLocalExternalDecls.clear(); // Now we snarf the rewritten text and stash it away for later use. - std::string Str = Rewrite.getRewrittenText(BE->getSourceRange()); + std::string Str = Rewrite.ConvertToString(BE->getBody()); RewrittenBlockExprs[BE] = Str; Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs); @@ -5714,7 +5736,7 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { RewriteTypeOfDecl(VD); } } - if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) { + if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) { if (isTopLevelBlockPointerType(TD->getUnderlyingType())) RewriteBlockPointerDecl(TD); else if (TD->getUnderlyingType()->isFunctionPointerType()) @@ -5884,7 +5906,7 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) { } return; } - if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { + if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { if (isTopLevelBlockPointerType(TD->getUnderlyingType())) RewriteBlockPointerDecl(TD); else if (TD->getUnderlyingType()->isFunctionPointerType()) diff --git a/contrib/llvm/tools/clang/lib/Rewrite/Rewriter.cpp b/contrib/llvm/tools/clang/lib/Rewrite/Rewriter.cpp index 92e2b03..51fe379 100644 --- a/contrib/llvm/tools/clang/lib/Rewrite/Rewriter.cpp +++ b/contrib/llvm/tools/clang/lib/Rewrite/Rewriter.cpp @@ -26,7 +26,23 @@ llvm::raw_ostream &RewriteBuffer::write(llvm::raw_ostream &os) const { return os; } -void RewriteBuffer::RemoveText(unsigned OrigOffset, unsigned Size) { +/// \brief Return true if this character is non-new-line whitespace: +/// ' ', '\t', '\f', '\v', '\r'. +static inline bool isWhitespace(unsigned char c) { + switch (c) { + case ' ': + case '\t': + case '\f': + case '\v': + case '\r': + return true; + default: + return false; + } +} + +void RewriteBuffer::RemoveText(unsigned OrigOffset, unsigned Size, + bool removeLineIfEmpty) { // Nothing to remove, exit early. if (Size == 0) return; @@ -38,6 +54,34 @@ void RewriteBuffer::RemoveText(unsigned OrigOffset, unsigned Size) { // Add a delta so that future changes are offset correctly. AddReplaceDelta(OrigOffset, -Size); + + if (removeLineIfEmpty) { + // Find the line that the remove occurred and if it is completely empty + // remove the line as well. + + iterator curLineStart = begin(); + unsigned curLineStartOffs = 0; + iterator posI = begin(); + for (unsigned i = 0; i != RealOffset; ++i) { + if (*posI == '\n') { + curLineStart = posI; + ++curLineStart; + curLineStartOffs = i + 1; + } + ++posI; + } + + unsigned lineSize = 0; + posI = curLineStart; + while (posI != end() && isWhitespace(*posI)) { + ++posI; + ++lineSize; + } + if (posI != end() && *posI == '\n') { + Buffer.erase(curLineStartOffs, lineSize + 1/* + '\n'*/); + AddReplaceDelta(curLineStartOffs, -(lineSize + 1/* + '\n'*/)); + } + } } void RewriteBuffer::InsertText(unsigned OrigOffset, llvm::StringRef Str, @@ -72,7 +116,8 @@ void RewriteBuffer::ReplaceText(unsigned OrigOffset, unsigned OrigLength, /// getRangeSize - Return the size in bytes of the specified range if they /// are in the same file. If not, this returns -1. -int Rewriter::getRangeSize(const CharSourceRange &Range) const { +int Rewriter::getRangeSize(const CharSourceRange &Range, + RewriteOptions opts) const { if (!isRewritable(Range.getBegin()) || !isRewritable(Range.getEnd())) return -1; @@ -91,8 +136,8 @@ int Rewriter::getRangeSize(const CharSourceRange &Range) const { RewriteBuffers.find(StartFileID); if (I != RewriteBuffers.end()) { const RewriteBuffer &RB = I->second; - EndOff = RB.getMappedOffset(EndOff, true); - StartOff = RB.getMappedOffset(StartOff); + EndOff = RB.getMappedOffset(EndOff, opts.IncludeInsertsAtEndOfRange); + StartOff = RB.getMappedOffset(StartOff, !opts.IncludeInsertsAtBeginOfRange); } @@ -104,8 +149,8 @@ int Rewriter::getRangeSize(const CharSourceRange &Range) const { return EndOff-StartOff; } -int Rewriter::getRangeSize(SourceRange Range) const { - return getRangeSize(CharSourceRange::getTokenRange(Range)); +int Rewriter::getRangeSize(SourceRange Range, RewriteOptions opts) const { + return getRangeSize(CharSourceRange::getTokenRange(Range), opts); } @@ -194,12 +239,24 @@ bool Rewriter::InsertText(SourceLocation Loc, llvm::StringRef Str, return false; } +bool Rewriter::InsertTextAfterToken(SourceLocation Loc, llvm::StringRef Str) { + if (!isRewritable(Loc)) return true; + FileID FID; + unsigned StartOffs = getLocationOffsetAndFileID(Loc, FID); + RewriteOptions rangeOpts; + rangeOpts.IncludeInsertsAtBeginOfRange = false; + StartOffs += getRangeSize(SourceRange(Loc, Loc), rangeOpts); + getEditBuffer(FID).InsertText(StartOffs, Str, /*InsertAfter*/true); + return false; +} + /// RemoveText - Remove the specified text region. -bool Rewriter::RemoveText(SourceLocation Start, unsigned Length) { +bool Rewriter::RemoveText(SourceLocation Start, unsigned Length, + RewriteOptions opts) { if (!isRewritable(Start)) return true; FileID FID; unsigned StartOffs = getLocationOffsetAndFileID(Start, FID); - getEditBuffer(FID).RemoveText(StartOffs, Length); + getEditBuffer(FID).RemoveText(StartOffs, Length, opts.RemoveLineIfEmpty); return false; } @@ -216,6 +273,20 @@ bool Rewriter::ReplaceText(SourceLocation Start, unsigned OrigLength, return false; } +bool Rewriter::ReplaceText(SourceRange range, SourceRange replacementRange) { + if (!isRewritable(range.getBegin())) return true; + if (!isRewritable(range.getEnd())) return true; + if (replacementRange.isInvalid()) return true; + SourceLocation start = range.getBegin(); + unsigned origLength = getRangeSize(range); + unsigned newLength = getRangeSize(replacementRange); + FileID FID; + unsigned newOffs = getLocationOffsetAndFileID(replacementRange.getBegin(), + FID); + llvm::StringRef MB = SourceMgr->getBufferData(FID); + return ReplaceText(start, origLength, MB.substr(newOffs, newLength)); +} + /// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty /// printer to generate the replacement code. This returns true if the input /// could not be rewritten, or false if successful. @@ -234,3 +305,93 @@ bool Rewriter::ReplaceStmt(Stmt *From, Stmt *To) { ReplaceText(From->getLocStart(), Size, Str); return false; } + +std::string Rewriter::ConvertToString(Stmt *From) { + std::string SStr; + llvm::raw_string_ostream S(SStr); + From->printPretty(S, 0, PrintingPolicy(*LangOpts)); + return S.str(); +} + +bool Rewriter::IncreaseIndentation(CharSourceRange range, + SourceLocation parentIndent) { + using llvm::StringRef; + + if (!isRewritable(range.getBegin())) return true; + if (!isRewritable(range.getEnd())) return true; + if (!isRewritable(parentIndent)) return true; + + FileID StartFileID, EndFileID, parentFileID; + unsigned StartOff, EndOff, parentOff; + + StartOff = getLocationOffsetAndFileID(range.getBegin(), StartFileID); + EndOff = getLocationOffsetAndFileID(range.getEnd(), EndFileID); + parentOff = getLocationOffsetAndFileID(parentIndent, parentFileID); + + if (StartFileID != EndFileID || StartFileID != parentFileID) + return true; + if (StartOff >= EndOff || parentOff >= StartOff) + return true; + + FileID FID = StartFileID; + StringRef MB = SourceMgr->getBufferData(FID); + + unsigned parentLineNo = SourceMgr->getLineNumber(FID, parentOff) - 1; + unsigned startLineNo = SourceMgr->getLineNumber(FID, StartOff) - 1; + unsigned endLineNo = SourceMgr->getLineNumber(FID, EndOff) - 1; + + const SrcMgr::ContentCache * + Content = SourceMgr->getSLocEntry(FID).getFile().getContentCache(); + + // Find where the line starts for the three offsets. + unsigned parentLineOffs = Content->SourceLineCache[parentLineNo]; + unsigned startLineOffs = Content->SourceLineCache[startLineNo]; + unsigned endLineOffs = Content->SourceLineCache[endLineNo]; + + if (startLineOffs == endLineOffs || startLineOffs == parentLineOffs) + return true; + + // Find the whitespace at the start of each line. + StringRef parentSpace, startSpace, endSpace; + { + unsigned i = parentLineOffs; + while (isWhitespace(MB[i])) + ++i; + parentSpace = MB.substr(parentLineOffs, i-parentLineOffs); + + i = startLineOffs; + while (isWhitespace(MB[i])) + ++i; + startSpace = MB.substr(startLineOffs, i-startLineOffs); + + i = endLineOffs; + while (isWhitespace(MB[i])) + ++i; + endSpace = MB.substr(endLineOffs, i-endLineOffs); + } + if (parentSpace.size() >= startSpace.size()) + return true; + if (!startSpace.startswith(parentSpace)) + return true; + + llvm::StringRef indent = startSpace.substr(parentSpace.size()); + + // Indent the lines between start/end offsets. + RewriteBuffer &RB = getEditBuffer(FID); + for (unsigned i = startLineOffs; i != endLineOffs; ++i) { + if (MB[i] == '\n') { + unsigned startOfLine = i+1; + if (startOfLine == endLineOffs) + break; + StringRef origIndent; + unsigned ws = startOfLine; + while (isWhitespace(MB[ws])) + ++ws; + origIndent = MB.substr(startOfLine, ws-startOfLine); + if (origIndent.startswith(startSpace)) + RB.InsertText(startOfLine, indent, /*InsertAfter=*/false); + } + } + + return false; +} |