From ab6677ec401cfd2c82b34e4cdfebd55a9dc25778 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 8 Sep 2010 00:15:04 +0000 Subject: [PATCH] Provide proper type-source location information for CXXTemporaryObjectExpr, CXXScalarValueInitExpr, and CXXUnresolvedConstructExpr, getting rid of a bunch of FIXMEs in the process. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113319 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ExprCXX.h | 80 ++++++++-------- include/clang/AST/RecursiveASTVisitor.h | 3 +- include/clang/Sema/Initialization.h | 23 ++++- include/clang/Sema/Sema.h | 8 +- lib/AST/ExprCXX.cpp | 41 +++++--- lib/AST/StmtPrinter.cpp | 6 +- lib/Parse/ParseExprCXX.cpp | 3 +- lib/Sema/SemaExprCXX.cpp | 49 ++++++---- lib/Sema/SemaInit.cpp | 18 +++- lib/Sema/TreeTransform.h | 118 ++++++++---------------- lib/Serialization/ASTReaderStmt.cpp | 9 +- lib/Serialization/ASTWriterStmt.cpp | 7 +- test/Index/load-stmts.cpp | 20 ++++ tools/libclang/CIndex.cpp | 29 +++++- 14 files changed, 237 insertions(+), 177 deletions(-) diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index b3012bf5d8..cdabc75868 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -804,24 +804,23 @@ public: /// }; /// @endcode class CXXTemporaryObjectExpr : public CXXConstructExpr { - SourceLocation TyBeginLoc; SourceLocation RParenLoc; + TypeSourceInfo *Type; public: CXXTemporaryObjectExpr(ASTContext &C, CXXConstructorDecl *Cons, - QualType writtenTy, SourceLocation tyBeginLoc, + TypeSourceInfo *Type, Expr **Args,unsigned NumArgs, SourceLocation rParenLoc, bool ZeroInitialization = false); explicit CXXTemporaryObjectExpr(EmptyShell Empty) - : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty) { } + : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty), Type() { } - SourceLocation getTypeBeginLoc() const { return TyBeginLoc; } + TypeSourceInfo *getTypeSourceInfo() const { return Type; } SourceLocation getRParenLoc() const { return RParenLoc; } - virtual SourceRange getSourceRange() const { - return SourceRange(TyBeginLoc, RParenLoc); - } + virtual SourceRange getSourceRange() const; + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXTemporaryObjectExprClass; } @@ -835,32 +834,30 @@ public: /// T, which is a non-class type. /// class CXXScalarValueInitExpr : public Expr { - SourceLocation TyBeginLoc; SourceLocation RParenLoc; + TypeSourceInfo *TypeInfo; + friend class ASTStmtReader; + public: - CXXScalarValueInitExpr(QualType ty, SourceLocation tyBeginLoc, - SourceLocation rParenLoc ) : - Expr(CXXScalarValueInitExprClass, ty, false, false), - TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {} + /// \brief Create an explicitly-written scalar-value initialization + /// expression. + CXXScalarValueInitExpr(QualType Type, + TypeSourceInfo *TypeInfo, + SourceLocation rParenLoc ) : + Expr(CXXScalarValueInitExprClass, Type, false, false), + RParenLoc(rParenLoc), TypeInfo(TypeInfo) {} + explicit CXXScalarValueInitExpr(EmptyShell Shell) : Expr(CXXScalarValueInitExprClass, Shell) { } - SourceLocation getTypeBeginLoc() const { return TyBeginLoc; } - SourceLocation getRParenLoc() const { return RParenLoc; } - - void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; } - void setRParenLoc(SourceLocation L) { RParenLoc = L; } - - /// @brief Whether this initialization expression was - /// implicitly-generated. - bool isImplicit() const { - return TyBeginLoc.isInvalid() && RParenLoc.isInvalid(); + TypeSourceInfo *getTypeSourceInfo() const { + return TypeInfo; } + + SourceLocation getRParenLoc() const { return RParenLoc; } - virtual SourceRange getSourceRange() const { - return SourceRange(TyBeginLoc, RParenLoc); - } + virtual SourceRange getSourceRange() const; static bool classof(const Stmt *T) { return T->getStmtClass() == CXXScalarValueInitExprClass; @@ -1838,12 +1835,9 @@ public: /// constructor call, conversion function call, or some kind of type /// conversion. class CXXUnresolvedConstructExpr : public Expr { - /// \brief The starting location of the type - SourceLocation TyBeginLoc; - /// \brief The type being constructed. - QualType Type; - + TypeSourceInfo *Type; + /// \brief The location of the left parentheses ('('). SourceLocation LParenLoc; @@ -1853,20 +1847,20 @@ class CXXUnresolvedConstructExpr : public Expr { /// \brief The number of arguments used to construct the type. unsigned NumArgs; - CXXUnresolvedConstructExpr(SourceLocation TyBegin, - QualType T, + CXXUnresolvedConstructExpr(TypeSourceInfo *Type, SourceLocation LParenLoc, Expr **Args, unsigned NumArgs, SourceLocation RParenLoc); CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs) - : Expr(CXXUnresolvedConstructExprClass, Empty), NumArgs(NumArgs) { } + : Expr(CXXUnresolvedConstructExprClass, Empty), Type(), NumArgs(NumArgs) { } + friend class ASTStmtReader; + public: static CXXUnresolvedConstructExpr *Create(ASTContext &C, - SourceLocation TyBegin, - QualType T, + TypeSourceInfo *Type, SourceLocation LParenLoc, Expr **Args, unsigned NumArgs, @@ -1875,15 +1869,14 @@ public: static CXXUnresolvedConstructExpr *CreateEmpty(ASTContext &C, unsigned NumArgs); - /// \brief Retrieve the source location where the type begins. - SourceLocation getTypeBeginLoc() const { return TyBeginLoc; } - void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; } - /// \brief Retrieve the type that is being constructed, as specified /// in the source code. - QualType getTypeAsWritten() const { return Type; } - void setTypeAsWritten(QualType T) { Type = T; } + QualType getTypeAsWritten() const { return Type->getType(); } + /// \brief Retrieve the type source information for the type being + /// constructed. + TypeSourceInfo *getTypeSourceInfo() const { return Type; } + /// \brief Retrieve the location of the left parentheses ('(') that /// precedes the argument list. SourceLocation getLParenLoc() const { return LParenLoc; } @@ -1924,9 +1917,8 @@ public: *(arg_begin() + I) = E; } - virtual SourceRange getSourceRange() const { - return SourceRange(TyBeginLoc, RParenLoc); - } + virtual SourceRange getSourceRange() const; + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXUnresolvedConstructExprClass; } diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 0a2adba58f..88ffd5ea2a 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1739,8 +1739,7 @@ bool RecursiveASTVisitor::TraverseInitListExpr(InitListExpr *S) { DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, { // This is called for code like 'return T()' where T is a built-in // (i.e. non-class) type. - if (!S->isImplicit()) - TRY_TO(TraverseType(S->getType())); + TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); }) DEF_TRAVERSE_STMT(CXXNewExpr, { diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h index 0062b3a29a..2ba6cdfd56 100644 --- a/include/clang/Sema/Initialization.h +++ b/include/clang/Sema/Initialization.h @@ -88,6 +88,10 @@ private: /// the VarDecl, ParmVarDecl, or FieldDecl, respectively. DeclaratorDecl *VariableOrMember; + /// \brief When Kind == EK_Temporary, the type source information for + /// the temporary. + TypeSourceInfo *TypeInfo; + struct { /// \brief When Kind == EK_Result, EK_Exception, or EK_New, the /// location of the 'return', 'throw', or 'new' keyword, @@ -189,7 +193,15 @@ public: static InitializedEntity InitializeTemporary(QualType Type) { return InitializedEntity(EK_Temporary, SourceLocation(), Type); } - + + /// \brief Create the initialization entity for a temporary. + static InitializedEntity InitializeTemporary(TypeSourceInfo *TypeInfo) { + InitializedEntity Result(EK_Temporary, SourceLocation(), + TypeInfo->getType()); + Result.TypeInfo = TypeInfo; + return Result; + } + /// \brief Create the initialization entity for a base class subobject. static InitializedEntity InitializeBase(ASTContext &Context, CXXBaseSpecifier *Base, @@ -219,6 +231,15 @@ public: /// \brief Retrieve type being initialized. QualType getType() const { return Type; } + /// \brief Retrieve complete type-source information for the object being + /// constructed, if known. + TypeSourceInfo *getTypeSourceInfo() const { + if (Kind == EK_Temporary) + return TypeInfo; + + return 0; + } + /// \brief Retrieve the name of the entity being initialized. DeclarationName getName() const; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 99228dc701..09119861dc 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2173,13 +2173,17 @@ public: /// Can be interpreted either as function-style casting ("int(x)") /// or class type construction ("ClassType(x,y,z)") /// or creation of a value-initialized type ("int()"). - ExprResult ActOnCXXTypeConstructExpr(SourceRange TypeRange, - ParsedType TypeRep, + ExprResult ActOnCXXTypeConstructExpr(ParsedType TypeRep, SourceLocation LParenLoc, MultiExprArg Exprs, SourceLocation *CommaLocs, SourceLocation RParenLoc); + ExprResult BuildCXXTypeConstructExpr(TypeSourceInfo *Type, + SourceLocation LParenLoc, + MultiExprArg Exprs, + SourceLocation RParenLoc); + /// ActOnCXXNew - Parsed a C++ 'new' expression. ExprResult ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, SourceLocation PlacementLParen, diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 11b223646b..8caf70b3e1 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -75,6 +75,13 @@ Stmt::child_iterator CXXDefaultArgExpr::child_end() { } // CXXScalarValueInitExpr +SourceRange CXXScalarValueInitExpr::getSourceRange() const { + SourceLocation Start = RParenLoc; + if (TypeInfo) + Start = TypeInfo->getTypeLoc().getBeginLoc(); + return SourceRange(Start, RParenLoc); +} + Stmt::child_iterator CXXScalarValueInitExpr::child_begin() { return child_iterator(); } @@ -691,15 +698,20 @@ CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(ASTContext &C, CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C, CXXConstructorDecl *Cons, - QualType writtenTy, - SourceLocation tyBeginLoc, + TypeSourceInfo *Type, Expr **Args, unsigned NumArgs, SourceLocation rParenLoc, bool ZeroInitialization) - : CXXConstructExpr(C, CXXTemporaryObjectExprClass, writtenTy, tyBeginLoc, + : CXXConstructExpr(C, CXXTemporaryObjectExprClass, + Type->getType().getNonReferenceType(), + Type->getTypeLoc().getBeginLoc(), Cons, false, Args, NumArgs, ZeroInitialization), - TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) { + RParenLoc(rParenLoc), Type(Type) { +} + +SourceRange CXXTemporaryObjectExpr::getSourceRange() const { + return SourceRange(Type->getTypeLoc().getBeginLoc(), RParenLoc); } CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, QualType T, @@ -791,17 +803,15 @@ Stmt::child_iterator CXXExprWithTemporaries::child_end() { return &SubExpr + 1; } -CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr( - SourceLocation TyBeginLoc, - QualType T, +CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *Type, SourceLocation LParenLoc, Expr **Args, unsigned NumArgs, SourceLocation RParenLoc) - : Expr(CXXUnresolvedConstructExprClass, T.getNonReferenceType(), - T->isDependentType(), true), - TyBeginLoc(TyBeginLoc), - Type(T), + : Expr(CXXUnresolvedConstructExprClass, + Type->getType().getNonReferenceType(), + Type->getType()->isDependentType(), true), + Type(Type), LParenLoc(LParenLoc), RParenLoc(RParenLoc), NumArgs(NumArgs) { @@ -811,15 +821,14 @@ CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr( CXXUnresolvedConstructExpr * CXXUnresolvedConstructExpr::Create(ASTContext &C, - SourceLocation TyBegin, - QualType T, + TypeSourceInfo *Type, SourceLocation LParenLoc, Expr **Args, unsigned NumArgs, SourceLocation RParenLoc) { void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) + sizeof(Expr *) * NumArgs); - return new (Mem) CXXUnresolvedConstructExpr(TyBegin, T, LParenLoc, + return new (Mem) CXXUnresolvedConstructExpr(Type, LParenLoc, Args, NumArgs, RParenLoc); } @@ -831,6 +840,10 @@ CXXUnresolvedConstructExpr::CreateEmpty(ASTContext &C, unsigned NumArgs) { return new (Mem) CXXUnresolvedConstructExpr(Empty, NumArgs); } +SourceRange CXXUnresolvedConstructExpr::getSourceRange() const { + return SourceRange(Type->getTypeLoc().getBeginLoc(), RParenLoc); +} + Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() { return child_iterator(reinterpret_cast(this + 1)); } diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 5236a66726..1778ce84d1 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -18,6 +18,7 @@ #include "clang/AST/PrettyPrinter.h" #include "llvm/Support/Format.h" #include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" using namespace clang; //===----------------------------------------------------------------------===// @@ -1051,7 +1052,10 @@ void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) { } void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) { - OS << Node->getType().getAsString(Policy) << "()"; + if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo()) + OS << TSInfo->getType().getAsString(Policy) << "()"; + else + OS << Node->getType().getAsString(Policy) << "()"; } void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) { diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 5041a21292..c48ae7ccc1 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -691,8 +691,7 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& "Unexpected number of commas!"); - return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep, - LParenLoc, move_arg(Exprs), + return Actions.ActOnCXXTypeConstructExpr(TypeRep, LParenLoc, move_arg(Exprs), CommaLocs.data(), RParenLoc); } diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 8e376c29f3..de9b599907 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -481,34 +481,43 @@ ExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) { return ExprError(Diag(ThisLoc, diag::err_invalid_this_use)); } -/// ActOnCXXTypeConstructExpr - Parse construction of a specified type. -/// Can be interpreted either as function-style casting ("int(x)") -/// or class type construction ("ClassType(x,y,z)") -/// or creation of a value-initialized type ("int()"). ExprResult -Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, ParsedType TypeRep, +Sema::ActOnCXXTypeConstructExpr(ParsedType TypeRep, SourceLocation LParenLoc, MultiExprArg exprs, SourceLocation *CommaLocs, SourceLocation RParenLoc) { if (!TypeRep) return ExprError(); - + TypeSourceInfo *TInfo; QualType Ty = GetTypeFromParser(TypeRep, &TInfo); if (!TInfo) TInfo = Context.getTrivialTypeSourceInfo(Ty, SourceLocation()); + + return BuildCXXTypeConstructExpr(TInfo, LParenLoc, exprs, RParenLoc); +} + +/// ActOnCXXTypeConstructExpr - Parse construction of a specified type. +/// Can be interpreted either as function-style casting ("int(x)") +/// or class type construction ("ClassType(x,y,z)") +/// or creation of a value-initialized type ("int()"). +ExprResult +Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, + SourceLocation LParenLoc, + MultiExprArg exprs, + SourceLocation RParenLoc) { + QualType Ty = TInfo->getType(); unsigned NumExprs = exprs.size(); Expr **Exprs = (Expr**)exprs.get(); - SourceLocation TyBeginLoc = TypeRange.getBegin(); + SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc(); SourceRange FullRange = SourceRange(TyBeginLoc, RParenLoc); if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs, NumExprs)) { exprs.release(); - return Owned(CXXUnresolvedConstructExpr::Create(Context, - TypeRange.getBegin(), Ty, + return Owned(CXXUnresolvedConstructExpr::Create(Context, TInfo, LParenLoc, Exprs, NumExprs, RParenLoc)); @@ -536,29 +545,29 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, ParsedType TypeRep, if (NumExprs == 1) { CastKind Kind = CK_Unknown; CXXCastPath BasePath; - if (CheckCastTypes(TypeRange, Ty, Exprs[0], Kind, BasePath, + if (CheckCastTypes(TInfo->getTypeLoc().getSourceRange(), Ty, Exprs[0], + Kind, BasePath, /*FunctionalStyle=*/true)) return ExprError(); exprs.release(); return Owned(CXXFunctionalCastExpr::Create(Context, - Ty.getNonLValueExprType(Context), + Ty.getNonLValueExprType(Context), TInfo, TyBeginLoc, Kind, Exprs[0], &BasePath, RParenLoc)); } if (Ty->isRecordType()) { - InitializedEntity Entity = InitializedEntity::InitializeTemporary(Ty); + InitializedEntity Entity = InitializedEntity::InitializeTemporary(TInfo); InitializationKind Kind - = NumExprs ? InitializationKind::CreateDirect(TypeRange.getBegin(), + = NumExprs ? InitializationKind::CreateDirect(TyBeginLoc, LParenLoc, RParenLoc) - : InitializationKind::CreateValue(TypeRange.getBegin(), + : InitializationKind::CreateValue(TyBeginLoc, LParenLoc, RParenLoc); InitializationSequence InitSeq(*this, Entity, Kind, Exprs, NumExprs); - ExprResult Result = InitSeq.Perform(*this, Entity, Kind, - move(exprs)); + ExprResult Result = InitSeq.Perform(*this, Entity, Kind, move(exprs)); // FIXME: Improve AST representation? return move(Result); @@ -569,18 +578,22 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, ParsedType TypeRep, // be a class with a suitably declared constructor. // if (NumExprs > 1) - return ExprError(Diag(CommaLocs[0], + return ExprError(Diag(PP.getLocForEndOfToken(Exprs[0]->getLocEnd()), diag::err_builtin_func_cast_more_than_one_arg) << FullRange); assert(NumExprs == 0 && "Expected 0 expressions"); + // FIXME: Why doesn't this go through the new-initialization code? + // C++ [expr.type.conv]p2: // The expression T(), where T is a simple-type-specifier for a non-array // complete object type or the (possibly cv-qualified) void type, creates an // rvalue of the specified type, which is value-initialized. // exprs.release(); - return Owned(new (Context) CXXScalarValueInitExpr(Ty, TyBeginLoc, RParenLoc)); + return Owned(new (Context) CXXScalarValueInitExpr( + TInfo->getType().getNonLValueExprType(Context), + TInfo, RParenLoc)); } diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index a28fd7fe12..64f5ac06b4 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -3843,10 +3843,14 @@ InitializationSequence::Perform(Sema &S, unsigned NumExprs = ConstructorArgs.size(); Expr **Exprs = (Expr **)ConstructorArgs.take(); S.MarkDeclarationReferenced(Loc, Constructor); + + TypeSourceInfo *TSInfo = Entity.getTypeSourceInfo(); + if (!TSInfo) + TSInfo = S.Context.getTrivialTypeSourceInfo(Entity.getType(), Loc); + CurInit = S.Owned(new (S.Context) CXXTemporaryObjectExpr(S.Context, Constructor, - Entity.getType(), - Loc, + TSInfo, Exprs, NumExprs, Kind.getParenRange().getEnd(), @@ -3901,8 +3905,14 @@ InitializationSequence::Perform(Sema &S, } else if (Kind.getKind() == InitializationKind::IK_Value && S.getLangOptions().CPlusPlus && !Kind.isImplicitValueInit()) { - CurInit = S.Owned(new (S.Context) CXXScalarValueInitExpr(Step->Type, - Kind.getRange().getBegin(), + TypeSourceInfo *TSInfo = Entity.getTypeSourceInfo(); + if (!TSInfo) + TSInfo = S.Context.getTrivialTypeSourceInfo(Step->Type, + Kind.getRange().getBegin()); + + CurInit = S.Owned(new (S.Context) CXXScalarValueInitExpr( + TSInfo->getType().getNonLValueExprType(S.Context), + TSInfo, Kind.getRange().getEnd())); } else { CurInit = S.Owned(new (S.Context) ImplicitValueInitExpr(Step->Type)); diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 0300143743..16114f2ca3 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1492,16 +1492,12 @@ public: /// /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange, - TypeSourceInfo *TInfo, - SourceLocation LParenLoc, - Expr *Sub, - SourceLocation RParenLoc) { - return getSema().ActOnCXXTypeConstructExpr(TypeRange, - ParsedType::make(TInfo->getType()), - LParenLoc, + ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo, + SourceLocation LParenLoc, + Expr *Sub, + SourceLocation RParenLoc) { + return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc, MultiExprArg(&Sub, 1), - /*CommaLocs=*/0, RParenLoc); } @@ -1565,14 +1561,12 @@ public: /// /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXScalarValueInitExpr(SourceLocation TypeStartLoc, - SourceLocation LParenLoc, - QualType T, - SourceLocation RParenLoc) { - return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc), - ParsedType::make(T), LParenLoc, + ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo, + SourceLocation LParenLoc, + SourceLocation RParenLoc) { + return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, MultiExprArg(getSema(), 0, 0), - 0, RParenLoc); + RParenLoc); } /// \brief Build a new C++ "new" expression. @@ -1685,17 +1679,13 @@ public: /// /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc, - QualType T, - SourceLocation LParenLoc, - MultiExprArg Args, - SourceLocation *Commas, - SourceLocation RParenLoc) { - return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc), - ParsedType::make(T), + ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo, + SourceLocation LParenLoc, + MultiExprArg Args, + SourceLocation RParenLoc) { + return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, move(Args), - Commas, RParenLoc); } @@ -1703,18 +1693,13 @@ public: /// /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc, - QualType T, - SourceLocation LParenLoc, - MultiExprArg Args, - SourceLocation *Commas, - SourceLocation RParenLoc) { - return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc, - /*FIXME*/LParenLoc), - ParsedType::make(T), + ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo, + SourceLocation LParenLoc, + MultiExprArg Args, + SourceLocation RParenLoc) { + return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, move(Args), - Commas, RParenLoc); } @@ -5113,10 +5098,7 @@ TreeTransform::TransformCXXFunctionalCastExpr( SubExpr.get() == E->getSubExpr()) return SemaRef.Owned(E->Retain()); - // FIXME: The end of the type's source range is wrong - return getDerived().RebuildCXXFunctionalCastExpr( - /*FIXME:*/SourceRange(E->getTypeBeginLoc()), - NewT, + return getDerived().RebuildCXXFunctionalCastExpr(NewT, /*FIXME:*/E->getSubExpr()->getLocStart(), SubExpr.get(), E->getRParenLoc()); @@ -5222,20 +5204,18 @@ TreeTransform::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) { template ExprResult -TreeTransform::TransformCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { - TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName()); - - QualType T = getDerived().TransformType(E->getType()); - if (T.isNull()) +TreeTransform::TransformCXXScalarValueInitExpr( + CXXScalarValueInitExpr *E) { + TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo()); + if (!T) return ExprError(); - + if (!getDerived().AlwaysRebuild() && - T == E->getType()) + T == E->getTypeSourceInfo()) return SemaRef.Owned(E->Retain()); - return getDerived().RebuildCXXScalarValueInitExpr(E->getTypeBeginLoc(), - /*FIXME:*/E->getTypeBeginLoc(), - T, + return getDerived().RebuildCXXScalarValueInitExpr(T, + /*FIXME:*/T->getTypeLoc().getEndLoc(), E->getRParenLoc()); } @@ -5709,10 +5689,9 @@ TreeTransform::TransformCXXExprWithTemporaries( template ExprResult TreeTransform::TransformCXXTemporaryObjectExpr( - CXXTemporaryObjectExpr *E) { - TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName()); - QualType T = getDerived().TransformType(E->getType()); - if (T.isNull()) + CXXTemporaryObjectExpr *E) { + TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo()); + if (!T) return ExprError(); CXXConstructorDecl *Constructor @@ -5742,26 +5721,17 @@ TreeTransform::TransformCXXTemporaryObjectExpr( } if (!getDerived().AlwaysRebuild() && - T == E->getType() && + T == E->getTypeSourceInfo() && Constructor == E->getConstructor() && !ArgumentChanged) { // FIXME: Instantiation-specific - SemaRef.MarkDeclarationReferenced(E->getTypeBeginLoc(), Constructor); + SemaRef.MarkDeclarationReferenced(E->getLocStart(), Constructor); return SemaRef.MaybeBindToTemporary(E->Retain()); } - - // FIXME: Bogus location information - SourceLocation CommaLoc; - if (Args.size() > 1) { - Expr *First = (Expr *)Args[0]; - CommaLoc - = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd()); - } - return getDerived().RebuildCXXTemporaryObjectExpr(E->getTypeBeginLoc(), - T, - /*FIXME:*/E->getTypeBeginLoc(), + + return getDerived().RebuildCXXTemporaryObjectExpr(T, + /*FIXME:*/T->getTypeLoc().getEndLoc(), move_arg(Args), - &CommaLoc, E->getLocEnd()); } @@ -5769,14 +5739,12 @@ template ExprResult TreeTransform::TransformCXXUnresolvedConstructExpr( CXXUnresolvedConstructExpr *E) { - TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName()); - QualType T = getDerived().TransformType(E->getTypeAsWritten()); - if (T.isNull()) + TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo()); + if (!T) return ExprError(); bool ArgumentChanged = false; ASTOwningVector Args(SemaRef); - llvm::SmallVector FakeCommaLocs; for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end(); Arg != ArgEnd; ++Arg) { @@ -5785,22 +5753,18 @@ TreeTransform::TransformCXXUnresolvedConstructExpr( return ExprError(); ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg; - FakeCommaLocs.push_back( - SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd())); Args.push_back(TransArg.get()); } if (!getDerived().AlwaysRebuild() && - T == E->getTypeAsWritten() && + T == E->getTypeSourceInfo() && !ArgumentChanged) return SemaRef.Owned(E->Retain()); // FIXME: we're faking the locations of the commas - return getDerived().RebuildCXXUnresolvedConstructExpr(E->getTypeBeginLoc(), - T, + return getDerived().RebuildCXXUnresolvedConstructExpr(T, E->getLParenLoc(), move_arg(Args), - FakeCommaLocs.data(), E->getRParenLoc()); } diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index d3efc71c83..8bfca9431d 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -974,7 +974,7 @@ void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) { void ASTStmtReader::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) { VisitCXXConstructExpr(E); - E->TyBeginLoc = Reader.ReadSourceLocation(Record, Idx); + E->Type = Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx); E->RParenLoc = Reader.ReadSourceLocation(Record, Idx); } @@ -1058,8 +1058,8 @@ void ASTStmtReader::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { void ASTStmtReader::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { VisitExpr(E); - E->setTypeBeginLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->TypeInfo = Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx); + E->RParenLoc = SourceLocation::getFromRawEncoding(Record[Idx++]); } void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) { @@ -1180,8 +1180,7 @@ ASTStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) { ++Idx; // NumArgs; for (unsigned I = 0, N = E->arg_size(); I != N; ++I) E->setArg(I, Reader.ReadSubExpr()); - E->setTypeBeginLoc(Reader.ReadSourceLocation(Record, Idx)); - E->setTypeAsWritten(Reader.GetType(Record[Idx++])); + E->Type = Reader.GetTypeSourceInfo(DeclsCursor, Record, Idx); E->setLParenLoc(Reader.ReadSourceLocation(Record, Idx)); E->setRParenLoc(Reader.ReadSourceLocation(Record, Idx)); } diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index b98b7e90a6..cda42e1098 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -977,7 +977,7 @@ void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) { void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) { VisitCXXConstructExpr(E); - Writer.AddSourceLocation(E->getTypeBeginLoc(), Record); + Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record); Writer.AddSourceLocation(E->getRParenLoc(), Record); Code = serialization::EXPR_CXX_TEMPORARY_OBJECT; } @@ -1076,7 +1076,7 @@ void ASTStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { void ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { VisitExpr(E); - Writer.AddSourceLocation(E->getTypeBeginLoc(), Record); + Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record); Writer.AddSourceLocation(E->getRParenLoc(), Record); Code = serialization::EXPR_CXX_SCALAR_VALUE_INIT; } @@ -1208,8 +1208,7 @@ ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) { for (CXXUnresolvedConstructExpr::arg_iterator ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI) Writer.AddStmt(*ArgI); - Writer.AddSourceLocation(E->getTypeBeginLoc(), Record); - Writer.AddTypeRef(E->getTypeAsWritten(), Record); + Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record); Writer.AddSourceLocation(E->getLParenLoc(), Record); Writer.AddSourceLocation(E->getRParenLoc(), Record); Code = serialization::EXPR_CXX_UNRESOLVED_CONSTRUCT; diff --git a/test/Index/load-stmts.cpp b/test/Index/load-stmts.cpp index c78f689989..bd2d7574ad 100644 --- a/test/Index/load-stmts.cpp +++ b/test/Index/load-stmts.cpp @@ -78,6 +78,16 @@ void *operator new(__SIZE_TYPE__, void*) throw(); void test_more_exprs(void *mem, int i, int j) { new (mem) Pair(i, j); + typedef int Integer; + (void)Integer(i); + (Integer)i; + Integer(); +} + +template +void test_even_more_dependent_exprs(T t, Y y) { + typedef T type; + (void)type(t, y); } // RUN: c-index-test -test-load-source all %s | FileCheck %s @@ -175,3 +185,13 @@ void test_more_exprs(void *mem, int i, int j) { // CHECK: load-stmts.cpp:80:13: TypeRef=struct Pair:73:8 Extent=[80:13 - 80:17] // CHECK: load-stmts.cpp:80:18: DeclRefExpr=i:79:37 Extent=[80:18 - 80:19] // CHECK: load-stmts.cpp:80:21: DeclRefExpr=j:79:44 Extent=[80:21 - 80:22] +// CHECK: load-stmts.cpp:82:9: TypeRef=Integer:81:15 Extent=[82:9 - 82:16] +// CHECK: load-stmts.cpp:82:17: DeclRefExpr=i:79:37 Extent=[82:17 - 82:18] +// CHECK: load-stmts.cpp:83:3: UnexposedExpr=i:79:37 Extent=[83:3 - 83:13] +// CHECK: load-stmts.cpp:83:4: TypeRef=Integer:81:15 Extent=[83:4 - 83:11] +// CHECK: load-stmts.cpp:83:12: DeclRefExpr=i:79:37 Extent=[83:12 - 83:13] +// CHECK: load-stmts.cpp:84:3: UnexposedExpr= Extent=[84:3 - 84:12] +// CHECK: load-stmts.cpp:84:3: TypeRef=Integer:81:15 Extent=[84:3 - 84:10] +// CHECK: load-stmts.cpp:90:9: TypeRef=type:89:13 Extent=[90:9 - 90:13] +// CHECK: load-stmts.cpp:90:14: DeclRefExpr=t:88:39 Extent=[90:14 - 90:15] +// CHECK: load-stmts.cpp:90:17: DeclRefExpr=y:88:44 Extent=[90:17 - 90:18] diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index c056e48542..a561b4a7f3 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -386,14 +386,14 @@ public: // FIXME: DesignatedInitExpr bool VisitCXXTypeidExpr(CXXTypeidExpr *E); bool VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { return false; } - // FIXME: CXXTemporaryObjectExpr has poor source-location information. - // FIXME: CXXScalarValueInitExpr has poor source-location information. + bool VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E); + bool VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E); bool VisitCXXNewExpr(CXXNewExpr *E); bool VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E); // FIXME: UnaryTypeTraitExpr has poor source-location information. bool VisitOverloadExpr(OverloadExpr *E); bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E); - // FIXME: CXXUnresolvedConstructExpr has poor source-location information. + bool VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E); bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); bool VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E); }; @@ -1590,6 +1590,20 @@ bool CursorVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) { return VisitExpr(E); } +bool CursorVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) { + if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo()) + return Visit(TSInfo->getTypeLoc()); + + return VisitExpr(E); +} + +bool CursorVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { + if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo()) + return Visit(TSInfo->getTypeLoc()); + + return false; +} + bool CursorVisitor::VisitCXXNewExpr(CXXNewExpr *E) { // Visit placement arguments. for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) @@ -1688,6 +1702,15 @@ bool CursorVisitor::VisitDependentScopeDeclRefExpr( return false; } +bool CursorVisitor::VisitCXXUnresolvedConstructExpr( + CXXUnresolvedConstructExpr *E) { + if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo()) + if (Visit(TSInfo->getTypeLoc())) + return true; + + return VisitExpr(E); +} + bool CursorVisitor::VisitCXXDependentScopeMemberExpr( CXXDependentScopeMemberExpr *E) { // Visit the base expression, if there is one. -- 2.50.1