summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Rewrite
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Rewrite')
-rw-r--r--contrib/llvm/tools/clang/lib/Rewrite/RewriteObjC.cpp160
-rw-r--r--contrib/llvm/tools/clang/lib/Rewrite/Rewriter.cpp177
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;
+}
OpenPOWER on IntegriCloud