From: John McCall Date: Mon, 18 Jan 2010 19:35:47 +0000 (+0000) Subject: Preserve type source information in compound literal expressions. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=42f56b50062cd3b3c6b23fdb9053578ae9145664;p=clang Preserve type source information in compound literal expressions. Patch by Enea Zaffanella! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93752 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 078a240a4c..2852c19744 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -1462,14 +1462,16 @@ class CompoundLiteralExpr : public Expr { /// 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) @@ -1485,6 +1487,9 @@ public: 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) diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp index c49f5e8fa4..21c9cbf17c 100644 --- a/lib/Frontend/PCHReaderStmt.cpp +++ b/lib/Frontend/PCHReaderStmt.cpp @@ -533,6 +533,7 @@ unsigned PCHStmtReader::VisitCStyleCastExpr(CStyleCastExpr *E) { unsigned PCHStmtReader::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { VisitExpr(E); E->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setTypeSourceInfo(Reader.GetTypeSourceInfo(Record, Idx)); E->setInitializer(cast(StmtStack.back())); E->setFileScope(Record[Idx++]); return 1; diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp index a5ad859b65..fdfdfefe08 100644 --- a/lib/Frontend/PCHWriterStmt.cpp +++ b/lib/Frontend/PCHWriterStmt.cpp @@ -496,6 +496,7 @@ void PCHStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) { 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; diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp index 68c23c708a..5a5b0eada3 100644 --- a/lib/Frontend/RewriteObjC.cpp +++ b/lib/Frontend/RewriteObjC.cpp @@ -2514,8 +2514,10 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { 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()), @@ -2597,7 +2599,10 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { 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 { diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index b273feb5b2..3e9deda811 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1666,13 +1666,18 @@ public: 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); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 31ec778390..eaf392116f 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3663,11 +3663,21 @@ Action::OwningExprResult 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(InitExpr.get()); if (literalType->isArrayType()) { @@ -3703,8 +3713,7 @@ Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty, 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)); } @@ -3912,13 +3921,13 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, TypeTy *Ty, 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(castExpr)) - return ActOnCastOfParenListExpr(S, LParenLoc, RParenLoc, move(Op),castType); + return ActOnCastOfParenListExpr(S, LParenLoc, RParenLoc, move(Op), + castTInfo); return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, move(Op)); } @@ -3973,8 +3982,9 @@ Sema::MaybeConvertParenListExprToParenExpr(Scope *S, ExprArg EA) { 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. @@ -3994,13 +4004,12 @@ Sema::ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc, 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)); } } @@ -4714,8 +4723,9 @@ static void ConstructTransparentUnion(ASTContext &C, Expr *&E, // 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 diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index aba6455df3..587c93d1ad 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1027,11 +1027,11 @@ public: /// 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. @@ -3853,28 +3853,21 @@ TreeTransform::TransformCStyleCastExpr(CStyleCastExpr *E) { template Sema::OwningExprResult TreeTransform::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)); }