summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2013-08-15 22:02:56 +0000
committerEli Friedman <eli.friedman@gmail.com>2013-08-15 22:02:56 +0000
commit89fe0d5842469f231c2a0649ff6d88ade892e6e8 (patch)
tree2e2d76928ebf201f5011b76e5c2340e4c01a780a /clang
parent35b22f69851dee2fb9e17d94ccf26967b5cf3399 (diff)
downloadbcm5719-llvm-89fe0d5842469f231c2a0649ff6d88ade892e6e8.tar.gz
bcm5719-llvm-89fe0d5842469f231c2a0649ff6d88ade892e6e8.zip
Properly track l-paren of a CXXFucntionalCastExpr.
In addition to storing more useful information in the AST, this fixes a semantic check in template instantiation which checks whether the l-paren location is valid. Fixes PR16903. llvm-svn: 188495
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/ExprCXX.h21
-rw-r--r--clang/lib/AST/Expr.cpp2
-rw-r--r--clang/lib/AST/ExprCXX.cpp16
-rw-r--r--clang/lib/Analysis/ReachableCode.cpp2
-rw-r--r--clang/lib/Sema/SemaCast.cpp4
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp5
-rw-r--r--clang/lib/Sema/TreeTransform.h2
-rw-r--r--clang/lib/Serialization/ASTReaderStmt.cpp2
-rw-r--r--clang/lib/Serialization/ASTWriterStmt.cpp2
-rw-r--r--clang/test/SemaTemplate/instantiate-init.cpp15
10 files changed, 46 insertions, 25 deletions
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 4a6cfae0681..cf3b88bd2a9 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -1206,17 +1206,16 @@ public:
/// x = int(0.5);
/// \endcode
class CXXFunctionalCastExpr : public ExplicitCastExpr {
- SourceLocation TyBeginLoc;
+ SourceLocation LParenLoc;
SourceLocation RParenLoc;
CXXFunctionalCastExpr(QualType ty, ExprValueKind VK,
TypeSourceInfo *writtenTy,
- SourceLocation tyBeginLoc, CastKind kind,
- Expr *castExpr, unsigned pathSize,
- SourceLocation rParenLoc)
+ CastKind kind, Expr *castExpr, unsigned pathSize,
+ SourceLocation lParenLoc, SourceLocation rParenLoc)
: ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind,
castExpr, pathSize, writtenTy),
- TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
+ LParenLoc(lParenLoc), RParenLoc(rParenLoc) {}
explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)
: ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) { }
@@ -1225,22 +1224,20 @@ public:
static CXXFunctionalCastExpr *Create(ASTContext &Context, QualType T,
ExprValueKind VK,
TypeSourceInfo *Written,
- SourceLocation TyBeginLoc,
CastKind Kind, Expr *Op,
const CXXCastPath *Path,
+ SourceLocation LPLoc,
SourceLocation RPLoc);
static CXXFunctionalCastExpr *CreateEmpty(ASTContext &Context,
unsigned PathSize);
- SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
- void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+ void setLParenLoc(SourceLocation L) { LParenLoc = L; }
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceLocation getLocStart() const LLVM_READONLY { return TyBeginLoc; }
- SourceLocation getLocEnd() const LLVM_READONLY {
- return RParenLoc.isValid() ? RParenLoc : getSubExpr()->getLocEnd();
- }
+ SourceLocation getLocStart() const LLVM_READONLY;
+ SourceLocation getLocEnd() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXFunctionalCastExprClass;
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 5c1a27da365..3eeb53e6201 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -2177,7 +2177,7 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
WarnE = this;
if (const CXXFunctionalCastExpr *CXXCE =
dyn_cast<CXXFunctionalCastExpr>(this)) {
- Loc = CXXCE->getTypeBeginLoc();
+ Loc = CXXCE->getLocStart();
R1 = CXXCE->getSubExpr()->getSourceRange();
} else {
const CStyleCastExpr *CStyleCE = cast<CStyleCastExpr>(this);
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index 055fc3b8142..0609eb1d65d 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -660,14 +660,14 @@ CXXConstCastExpr *CXXConstCastExpr::CreateEmpty(ASTContext &C) {
CXXFunctionalCastExpr *
CXXFunctionalCastExpr::Create(ASTContext &C, QualType T, ExprValueKind VK,
- TypeSourceInfo *Written, SourceLocation L,
- CastKind K, Expr *Op, const CXXCastPath *BasePath,
- SourceLocation R) {
+ TypeSourceInfo *Written, CastKind K, Expr *Op,
+ const CXXCastPath *BasePath,
+ SourceLocation L, SourceLocation R) {
unsigned PathSize = (BasePath ? BasePath->size() : 0);
void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr)
+ PathSize * sizeof(CXXBaseSpecifier*));
CXXFunctionalCastExpr *E =
- new (Buffer) CXXFunctionalCastExpr(T, VK, Written, L, K, Op, PathSize, R);
+ new (Buffer) CXXFunctionalCastExpr(T, VK, Written, K, Op, PathSize, L, R);
if (PathSize) E->setCastPath(*BasePath);
return E;
}
@@ -679,6 +679,14 @@ CXXFunctionalCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) {
return new (Buffer) CXXFunctionalCastExpr(EmptyShell(), PathSize);
}
+SourceLocation CXXFunctionalCastExpr::getLocStart() const {
+ return getTypeInfoAsWritten()->getTypeLoc().getLocStart();
+}
+
+SourceLocation CXXFunctionalCastExpr::getLocEnd() const {
+ return RParenLoc.isValid() ? RParenLoc : getSubExpr()->getLocEnd();
+}
+
UserDefinedLiteral::LiteralOperatorKind
UserDefinedLiteral::getLiteralOperatorKind() const {
if (getNumArgs() == 0)
diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp
index a90aebbe28e..e15fe7d1266 100644
--- a/clang/lib/Analysis/ReachableCode.cpp
+++ b/clang/lib/Analysis/ReachableCode.cpp
@@ -227,7 +227,7 @@ static SourceLocation GetUnreachableLoc(const Stmt *S,
case Expr::CXXFunctionalCastExprClass: {
const CXXFunctionalCastExpr *CE = cast <CXXFunctionalCastExpr>(S);
R1 = CE->getSubExpr()->getSourceRange();
- return CE->getTypeBeginLoc();
+ return CE->getLocStart();
}
case Stmt::CXXTryStmtClass: {
return cast<CXXTryStmt>(S)->getHandler(0)->getCatchLoc();
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 888c14ec392..e3227bcaefe 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -2364,6 +2364,6 @@ ExprResult Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo,
ConstructExpr->setParenRange(SourceRange(LPLoc, RPLoc));
return Op.complete(CXXFunctionalCastExpr::Create(Context, Op.ResultType,
- Op.ValueKind, CastTypeInfo, Op.DestRange.getBegin(),
- Op.Kind, Op.SrcExpr.take(), &Op.BasePath, RPLoc));
+ Op.ValueKind, CastTypeInfo, Op.Kind,
+ Op.SrcExpr.take(), &Op.BasePath, LPLoc, RPLoc));
}
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index ee2eb6d02f6..0b58a3d86d8 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -902,8 +902,9 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
InitListExpr *List = cast<InitListExpr>(Result.take());
Result = Owned(CXXFunctionalCastExpr::Create(Context, List->getType(),
Expr::getValueKindForType(TInfo->getType()),
- TInfo, TyBeginLoc, CK_NoOp,
- List, /*Path=*/0, RParenLoc));
+ TInfo, CK_NoOp, List,
+ /*Path=*/0,
+ LParenLoc, RParenLoc));
}
// FIXME: Improve AST representation?
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index b3e8720f5e6..9e5738394ea 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -7317,7 +7317,7 @@ TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
return SemaRef.Owned(E);
return getDerived().RebuildCXXFunctionalCastExpr(Type,
- /*FIXME:*/E->getSubExpr()->getLocStart(),
+ E->getLParenLoc(),
SubExpr.get(),
E->getRParenLoc());
}
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index c0193c37726..eaea0f905cb 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -1263,7 +1263,7 @@ void ASTStmtReader::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
void ASTStmtReader::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
VisitExplicitCastExpr(E);
- E->setTypeBeginLoc(ReadSourceLocation(Record, Idx));
+ E->setLParenLoc(ReadSourceLocation(Record, Idx));
E->setRParenLoc(ReadSourceLocation(Record, Idx));
}
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 533496d5dc4..95b96766875 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1226,7 +1226,7 @@ void ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
VisitExplicitCastExpr(E);
- Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
+ Writer.AddSourceLocation(E->getLParenLoc(), Record);
Writer.AddSourceLocation(E->getRParenLoc(), Record);
Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
}
diff --git a/clang/test/SemaTemplate/instantiate-init.cpp b/clang/test/SemaTemplate/instantiate-init.cpp
index 6a1a57ca659..22c70be3a8d 100644
--- a/clang/test/SemaTemplate/instantiate-init.cpp
+++ b/clang/test/SemaTemplate/instantiate-init.cpp
@@ -118,3 +118,18 @@ namespace PR13064 {
template<typename T> struct C { T a = { 0 }; }; // expected-error{{explicit}}
C<A> c; // expected-note{{here}}
}
+
+namespace PR16903 {
+ // Make sure we properly instantiate list-initialization.
+ template<typename T>
+ void fun (T it) {
+ int m = 0;
+ for (int i = 0; i < 4; ++i, ++it){
+ m |= long{char{*it}};
+ }
+ }
+ int test() {
+ char in[4] = {0,0,0,0};
+ fun(in);
+ }
+}
OpenPOWER on IntegriCloud