diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ExprCXX.cpp | 20 | ||||
-rw-r--r-- | lib/Sema/SemaCast.cpp | 12 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 44 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 12 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 2 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 1 |
6 files changed, 63 insertions, 28 deletions
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 4b520e4fdf..e1e96e4c5c 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -526,13 +526,14 @@ CXXStaticCastExpr *CXXStaticCastExpr::Create(ASTContext &C, QualType T, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L, - SourceLocation RParenLoc) { + SourceLocation RParenLoc, + SourceRange AngleBrackets) { unsigned PathSize = (BasePath ? BasePath->size() : 0); void *Buffer = C.Allocate(sizeof(CXXStaticCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); CXXStaticCastExpr *E = new (Buffer) CXXStaticCastExpr(T, VK, K, Op, PathSize, WrittenTy, L, - RParenLoc); + RParenLoc, AngleBrackets); if (PathSize) E->setCastPath(*BasePath); return E; } @@ -550,13 +551,14 @@ CXXDynamicCastExpr *CXXDynamicCastExpr::Create(ASTContext &C, QualType T, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L, - SourceLocation RParenLoc) { + SourceLocation RParenLoc, + SourceRange AngleBrackets) { unsigned PathSize = (BasePath ? BasePath->size() : 0); void *Buffer = C.Allocate(sizeof(CXXDynamicCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); CXXDynamicCastExpr *E = new (Buffer) CXXDynamicCastExpr(T, VK, K, Op, PathSize, WrittenTy, L, - RParenLoc); + RParenLoc, AngleBrackets); if (PathSize) E->setCastPath(*BasePath); return E; } @@ -606,13 +608,14 @@ CXXReinterpretCastExpr::Create(ASTContext &C, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L, - SourceLocation RParenLoc) { + SourceLocation RParenLoc, + SourceRange AngleBrackets) { unsigned PathSize = (BasePath ? BasePath->size() : 0); void *Buffer = C.Allocate(sizeof(CXXReinterpretCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); CXXReinterpretCastExpr *E = new (Buffer) CXXReinterpretCastExpr(T, VK, K, Op, PathSize, WrittenTy, L, - RParenLoc); + RParenLoc, AngleBrackets); if (PathSize) E->setCastPath(*BasePath); return E; } @@ -628,8 +631,9 @@ CXXConstCastExpr *CXXConstCastExpr::Create(ASTContext &C, QualType T, ExprValueKind VK, Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L, - SourceLocation RParenLoc) { - return new (C) CXXConstCastExpr(T, VK, Op, WrittenTy, L, RParenLoc); + SourceLocation RParenLoc, + SourceRange AngleBrackets) { + return new (C) CXXConstCastExpr(T, VK, Op, WrittenTy, L, RParenLoc, AngleBrackets); } CXXConstCastExpr *CXXConstCastExpr::CreateEmpty(ASTContext &C) { diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp index e6dc0bd8bc..3f46cd457a 100644 --- a/lib/Sema/SemaCast.cpp +++ b/lib/Sema/SemaCast.cpp @@ -258,7 +258,8 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, } return Op.complete(CXXConstCastExpr::Create(Context, Op.ResultType, Op.ValueKind, Op.SrcExpr.take(), DestTInfo, - OpLoc, Parens.getEnd())); + OpLoc, Parens.getEnd(), + AngleBrackets)); case tok::kw_dynamic_cast: { if (!TypeDependent) { @@ -269,7 +270,8 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, return Op.complete(CXXDynamicCastExpr::Create(Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.take(), &Op.BasePath, DestTInfo, - OpLoc, Parens.getEnd())); + OpLoc, Parens.getEnd(), + AngleBrackets)); } case tok::kw_reinterpret_cast: { if (!TypeDependent) { @@ -280,7 +282,8 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, return Op.complete(CXXReinterpretCastExpr::Create(Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.take(), 0, DestTInfo, OpLoc, - Parens.getEnd())); + Parens.getEnd(), + AngleBrackets)); } case tok::kw_static_cast: { if (!TypeDependent) { @@ -292,7 +295,8 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, return Op.complete(CXXStaticCastExpr::Create(Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.take(), &Op.BasePath, DestTInfo, - OpLoc, Parens.getEnd())); + OpLoc, Parens.getEnd(), + AngleBrackets)); } } } diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 2dbba853e4..b26fa7661c 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -2810,19 +2810,36 @@ static void addFixitForObjCARCConversion(Sema &S, SourceLocation afterLParen, QualType castType, Expr *castExpr, + Expr *realCast, const char *bridgeKeyword, const char *CFBridgeName) { // We handle C-style and implicit casts here. switch (CCK) { case Sema::CCK_ImplicitConversion: case Sema::CCK_CStyleCast: + case Sema::CCK_OtherCast: break; case Sema::CCK_FunctionalCast: - case Sema::CCK_OtherCast: return; } if (CFBridgeName) { + if (CCK == Sema::CCK_OtherCast) { + if (const CXXNamedCastExpr *NCE = dyn_cast<CXXNamedCastExpr>(realCast)) { + SourceRange range(NCE->getOperatorLoc(), + NCE->getAngleBrackets().getEnd()); + SmallString<32> BridgeCall; + + SourceManager &SM = S.getSourceManager(); + char PrevChar = *SM.getCharacterData(range.getBegin().getLocWithOffset(-1)); + if (Lexer::isIdentifierBodyChar(PrevChar, S.getLangOpts())) + BridgeCall += ' '; + + BridgeCall += CFBridgeName; + DiagB.AddFixItHint(FixItHint::CreateReplacement(range, BridgeCall)); + } + return; + } Expr *castedE = castExpr; if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(castedE)) castedE = CCE->getSubExpr(); @@ -2854,6 +2871,16 @@ static void addFixitForObjCARCConversion(Sema &S, if (CCK == Sema::CCK_CStyleCast) { DiagB.AddFixItHint(FixItHint::CreateInsertion(afterLParen, bridgeKeyword)); + } else if (CCK == Sema::CCK_OtherCast) { + if (const CXXNamedCastExpr *NCE = dyn_cast<CXXNamedCastExpr>(realCast)) { + std::string castCode = "("; + castCode += bridgeKeyword; + castCode += castType.getAsString(); + castCode += ")"; + SourceRange Range(NCE->getOperatorLoc(), + NCE->getAngleBrackets().getEnd()); + DiagB.AddFixItHint(FixItHint::CreateReplacement(Range, castCode)); + } } else { std::string castCode = "("; castCode += bridgeKeyword; @@ -2878,7 +2905,8 @@ static void addFixitForObjCARCConversion(Sema &S, static void diagnoseObjCARCConversion(Sema &S, SourceRange castRange, QualType castType, ARCConversionTypeClass castACTC, - Expr *castExpr, ARCConversionTypeClass exprACTC, + Expr *castExpr, Expr *realCast, + ARCConversionTypeClass exprACTC, Sema::CheckedConversionKind CCK) { SourceLocation loc = (castRange.isValid() ? castRange.getBegin() : castExpr->getExprLoc()); @@ -2930,7 +2958,7 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange, : S.Diag(noteLoc, diag::note_arc_cstyle_bridge); addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen, - castType, castExpr, "__bridge ", 0); + castType, castExpr, realCast, "__bridge ", 0); } if (CreateRule != ACC_plusZero) { @@ -2942,7 +2970,7 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange, << castExprType << br; addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen, - castType, castExpr, "__bridge_transfer ", + castType, castExpr, realCast, "__bridge_transfer ", br ? "CFBridgingRelease" : 0); } @@ -2969,7 +2997,7 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange, (CCK != Sema::CCK_OtherCast) ? S.Diag(noteLoc, diag::note_arc_bridge) : S.Diag(noteLoc, diag::note_arc_cstyle_bridge); addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen, - castType, castExpr, "__bridge ", 0); + castType, castExpr, realCast, "__bridge ", 0); } if (CreateRule != ACC_plusZero) { @@ -2981,7 +3009,7 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange, << castType << br; addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen, - castType, castExpr, "__bridge_retained ", + castType, castExpr, realCast, "__bridge_retained ", br ? "CFBridgingRetain" : 0); } @@ -3078,7 +3106,7 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType, return ACR_unbridged; diagnoseObjCARCConversion(*this, castRange, castType, castACTC, - castExpr, exprACTC, CCK); + castExpr, castExpr, exprACTC, CCK); return ACR_okay; } @@ -3113,7 +3141,7 @@ void Sema::diagnoseARCUnbridgedCast(Expr *e) { assert(classifyTypeForARCConversion(castExpr->getType()) == ACTC_retainable); diagnoseObjCARCConversion(*this, castRange, castType, castACTC, - castExpr, ACTC_retainable, CCK); + castExpr, realCast, ACTC_retainable, CCK); } /// stripARCUnbridgedCast - Given an expression of ARCUnbridgedCast diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 438d06a8ef..66bf4cea68 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -7022,17 +7022,13 @@ TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) { Type == E->getTypeInfoAsWritten() && SubExpr.get() == E->getSubExpr()) return SemaRef.Owned(E); - - // FIXME: Poor source location information here. - SourceLocation FakeLAngleLoc - = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc()); - SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin(); return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(), E->getStmtClass(), - FakeLAngleLoc, + E->getAngleBrackets().getBegin(), Type, - FakeRAngleLoc, - FakeRAngleLoc, + E->getAngleBrackets().getEnd(), + // FIXME. this should be '(' location + E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc()); } diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index 7f26a1752b..9c99d6e46f 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -1147,6 +1147,8 @@ void ASTStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) { SourceRange R = ReadSourceRange(Record, Idx); E->Loc = R.getBegin(); E->RParenLoc = R.getEnd(); + R = ReadSourceRange(Record, Idx); + E->AngleBrackets = R; } void ASTStmtReader::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) { diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 6b96c500c3..ee9735c163 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -1124,6 +1124,7 @@ void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) { VisitExplicitCastExpr(E); Writer.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()), Record); + Writer.AddSourceRange(E->getAngleBrackets(), Record); } void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) { |