aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ExprCXX.cpp20
-rw-r--r--lib/Sema/SemaCast.cpp12
-rw-r--r--lib/Sema/SemaExprObjC.cpp44
-rw-r--r--lib/Sema/TreeTransform.h12
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp2
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp1
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) {