/// compound literal like "(int){4}". This can be null if this is a
/// synthesized compound expression.
SourceLocation LParenLoc;
+ TypeSourceInfo *TInfo;
Stmt *Init;
bool FileScope;
public:
// FIXME: Can compound literals be value-dependent?
- CompoundLiteralExpr(SourceLocation lparenloc, QualType ty, Expr *init,
- bool fileScope)
- : Expr(CompoundLiteralExprClass, ty, ty->isDependentType(), false),
- LParenLoc(lparenloc), Init(init), FileScope(fileScope) {}
+ CompoundLiteralExpr(SourceLocation lparenloc, TypeSourceInfo *tinfo,
+ Expr *init, bool fileScope)
+ : Expr(CompoundLiteralExprClass, tinfo->getType(),
+ tinfo->getType()->isDependentType(), false),
+ LParenLoc(lparenloc), TInfo(tinfo), Init(init), FileScope(fileScope) {}
/// \brief Construct an empty compound literal.
explicit CompoundLiteralExpr(EmptyShell Empty)
SourceLocation getLParenLoc() const { return LParenLoc; }
void setLParenLoc(SourceLocation L) { LParenLoc = L; }
+ TypeSourceInfo *getTypeSourceInfo() const { return TInfo; }
+ void setTypeSourceInfo(TypeSourceInfo* tinfo) { TInfo = tinfo; }
+
virtual SourceRange getSourceRange() const {
// FIXME: Init should never be null.
if (!Init)
unsigned PCHStmtReader::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
VisitExpr(E);
E->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ E->setTypeSourceInfo(Reader.GetTypeSourceInfo(Record, Idx));
E->setInitializer(cast<Expr>(StmtStack.back()));
E->setFileScope(Record[Idx++]);
return 1;
void PCHStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
VisitExpr(E);
Writer.AddSourceLocation(E->getLParenLoc(), Record);
+ Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
Writer.WriteSubStmt(E->getInitializer());
Record.push_back(E->isFileScope());
Code = pch::EXPR_COMPOUND_LITERAL;
InitListExpr *ILE = new (Context) InitListExpr(SourceLocation(),
&InitExprs[0], InitExprs.size(),
SourceLocation());
- SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superType, ILE,
- false);
+ TypeSourceInfo *superTInfo
+ = Context->getTrivialTypeSourceInfo(superType);
+ SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(),
+ superTInfo, ILE, false);
// struct objc_super *
SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
Context->getPointerType(SuperRep->getType()),
InitListExpr *ILE = new (Context) InitListExpr(SourceLocation(),
&InitExprs[0], InitExprs.size(),
SourceLocation());
- SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superType, ILE, false);
+ TypeSourceInfo *superTInfo
+ = Context->getTrivialTypeSourceInfo(superType);
+ SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(),
+ superTInfo, ILE, false);
}
MsgExprs.push_back(SuperRep);
} else {
OwningExprResult MaybeConvertParenListExprToParenExpr(Scope *S, ExprArg ME);
OwningExprResult ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc,
SourceLocation RParenLoc, ExprArg E,
- QualType Ty);
+ TypeSourceInfo *TInfo);
virtual OwningExprResult ActOnCompoundLiteral(SourceLocation LParenLoc,
TypeTy *Ty,
SourceLocation RParenLoc,
ExprArg Op);
+ OwningExprResult BuildCompoundLiteralExpr(SourceLocation LParenLoc,
+ TypeSourceInfo *TInfo,
+ SourceLocation RParenLoc,
+ ExprArg InitExpr);
+
virtual OwningExprResult ActOnInitList(SourceLocation LParenLoc,
MultiExprArg InitList,
SourceLocation RParenLoc);
Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty,
SourceLocation RParenLoc, ExprArg InitExpr) {
assert((Ty != 0) && "ActOnCompoundLiteral(): missing type");
-
- QualType literalType = GetTypeFromParser(Ty);
-
// FIXME: put back this assert when initializers are worked out.
//assert((InitExpr != 0) && "ActOnCompoundLiteral(): missing expression");
+
+ TypeSourceInfo *TInfo;
+ QualType literalType = GetTypeFromParser(Ty, &TInfo);
+ if (!TInfo)
+ TInfo = Context.getTrivialTypeSourceInfo(literalType);
+
+ return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, move(InitExpr));
+}
+
+Action::OwningExprResult
+Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
+ SourceLocation RParenLoc, ExprArg InitExpr) {
+ QualType literalType = TInfo->getType();
Expr *literalExpr = static_cast<Expr*>(InitExpr.get());
if (literalType->isArrayType()) {
Result.release();
- // FIXME: Store the TInfo to preserve type information better.
- return Owned(new (Context) CompoundLiteralExpr(LParenLoc, literalType,
+ return Owned(new (Context) CompoundLiteralExpr(LParenLoc, TInfo,
literalExpr, isFileScope));
}
TypeSourceInfo *castTInfo;
QualType castType = GetTypeFromParser(Ty, &castTInfo);
if (!castTInfo)
- castTInfo = Context.getTrivialTypeSourceInfo(castType, SourceLocation());
+ castTInfo = Context.getTrivialTypeSourceInfo(castType);
// If the Expr being casted is a ParenListExpr, handle it specially.
- // FIXME: preserve type source info.
Expr *castExpr = (Expr *)Op.get();
if (isa<ParenListExpr>(castExpr))
- return ActOnCastOfParenListExpr(S, LParenLoc, RParenLoc, move(Op),castType);
+ return ActOnCastOfParenListExpr(S, LParenLoc, RParenLoc, move(Op),
+ castTInfo);
return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, move(Op));
}
Action::OwningExprResult
Sema::ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc,
SourceLocation RParenLoc, ExprArg Op,
- QualType Ty) {
+ TypeSourceInfo *TInfo) {
ParenListExpr *PE = (ParenListExpr *)Op.get();
+ QualType Ty = TInfo->getType();
// If this is an altivec initializer, '(' type ')' '(' init, ..., init ')'
// then handle it as such.
InitListExpr *E = new (Context) InitListExpr(LParenLoc, &initExprs[0],
initExprs.size(), RParenLoc);
E->setType(Ty);
- return ActOnCompoundLiteral(LParenLoc, Ty.getAsOpaquePtr(), RParenLoc,
- Owned(E));
+ return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, Owned(E));
} else {
// This is not an AltiVec-style cast, so turn the ParenListExpr into a
// sequence of BinOp comma operators.
Op = MaybeConvertParenListExprToParenExpr(S, move(Op));
- return ActOnCastExpr(S, LParenLoc, Ty.getAsOpaquePtr(), RParenLoc,move(Op));
+ return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, move(Op));
}
}
// Build a compound literal constructing a value of the transparent
// union type from this initializer list.
- E = new (C) CompoundLiteralExpr(SourceLocation(), UnionType, Initializer,
- false);
+ TypeSourceInfo *unionTInfo = C.getTrivialTypeSourceInfo(UnionType);
+ E = new (C) CompoundLiteralExpr(SourceLocation(), unionTInfo,
+ Initializer, false);
}
Sema::AssignConvertType
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
OwningExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
- QualType T,
+ TypeSourceInfo *TInfo,
SourceLocation RParenLoc,
ExprArg Init) {
- return getSema().ActOnCompoundLiteral(LParenLoc, T.getAsOpaquePtr(),
- RParenLoc, move(Init));
+ return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
+ move(Init));
}
/// \brief Build a new extended vector element access expression.
template<typename Derived>
Sema::OwningExprResult
TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
- QualType T;
- {
- // FIXME: Source location isn't quite accurate.
- SourceLocation FakeTypeLoc
- = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
- TemporaryBase Rebase(*this, FakeTypeLoc, DeclarationName());
-
- T = getDerived().TransformType(E->getType());
- if (T.isNull())
- return SemaRef.ExprError();
- }
+ TypeSourceInfo *OldT = E->getTypeSourceInfo();
+ TypeSourceInfo *NewT = getDerived().TransformType(OldT);
+ if (!NewT)
+ return SemaRef.ExprError();
OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
if (Init.isInvalid())
return SemaRef.ExprError();
if (!getDerived().AlwaysRebuild() &&
- T == E->getType() &&
+ OldT == NewT &&
Init.get() == E->getInitializer())
return SemaRef.Owned(E->Retain());
- return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), T,
+ return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), NewT,
/*FIXME:*/E->getInitializer()->getLocEnd(),
move(Init));
}