From 58f10c3380640962d251db70ac876e5ea7336c59 Mon Sep 17 00:00:00 2001 From: John McCall Date: Thu, 11 Mar 2010 09:03:00 +0000 Subject: Maintain type source information for functions through template instantiation. Based on a patch by Enea Zaffanella! I found a way to reduce some of the redundancy between TreeTransform's "standard" FunctionProtoType transformation and TemplateInstantiator's override, and I killed off the old SubstFunctionType by adding type source info for the last cases where we were creating FunctionDecls without TSI (at least that get passed through template instantiation). llvm-svn: 98252 --- clang/lib/Sema/TreeTransform.h | 96 +++++++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 30 deletions(-) (limited to 'clang/lib/Sema/TreeTransform.h') diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 17f94193fed..61091cdcc04 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -315,6 +315,21 @@ public: QualType ObjectType = QualType()); #include "clang/AST/TypeLocNodes.def" + /// \brief Transforms the parameters of a function type into the + /// given vectors. + /// + /// The result vectors should be kept in sync; null entries in the + /// variables vector are acceptable. + /// + /// Return true on error. + bool TransformFunctionTypeParams(FunctionProtoTypeLoc TL, + llvm::SmallVectorImpl &PTypes, + llvm::SmallVectorImpl &PVars); + + /// \brief Transforms a single function-type parameter. Return null + /// on error. + ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm); + QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL, QualType ObjectType); @@ -2520,18 +2535,33 @@ QualType TreeTransform::TransformExtVectorType(TypeLocBuilder &TLB, } template -QualType -TreeTransform::TransformFunctionProtoType(TypeLocBuilder &TLB, - FunctionProtoTypeLoc TL, - QualType ObjectType) { +ParmVarDecl * +TreeTransform::TransformFunctionTypeParam(ParmVarDecl *OldParm) { + TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo(); + TypeSourceInfo *NewDI = getDerived().TransformType(OldDI); + if (!NewDI) + return 0; + + if (NewDI == OldDI) + return OldParm; + else + return ParmVarDecl::Create(SemaRef.Context, + OldParm->getDeclContext(), + OldParm->getLocation(), + OldParm->getIdentifier(), + NewDI->getType(), + NewDI, + OldParm->getStorageClass(), + /* DefArg */ NULL); +} + +template +bool TreeTransform:: + TransformFunctionTypeParams(FunctionProtoTypeLoc TL, + llvm::SmallVectorImpl &PTypes, + llvm::SmallVectorImpl &PVars) { FunctionProtoType *T = TL.getTypePtr(); - QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc()); - if (ResultType.isNull()) - return QualType(); - // Transform the parameters. - llvm::SmallVector ParamTypes; - llvm::SmallVector ParamDecls; for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) { ParmVarDecl *OldParm = TL.getArg(i); @@ -2539,24 +2569,11 @@ TreeTransform::TransformFunctionProtoType(TypeLocBuilder &TLB, ParmVarDecl *NewParm; if (OldParm) { - TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo(); - assert(OldDI->getType() == T->getArgType(i)); + assert(OldParm->getTypeSourceInfo()->getType() == T->getArgType(i)); - TypeSourceInfo *NewDI = getDerived().TransformType(OldDI); - if (!NewDI) - return QualType(); - - if (NewDI == OldDI) - NewParm = OldParm; - else - NewParm = ParmVarDecl::Create(SemaRef.Context, - OldParm->getDeclContext(), - OldParm->getLocation(), - OldParm->getIdentifier(), - NewDI->getType(), - NewDI, - OldParm->getStorageClass(), - /* DefArg */ NULL); + NewParm = getDerived().TransformFunctionTypeParam(OldParm); + if (!NewParm) + return true; NewType = NewParm->getType(); // Deal with the possibility that we don't have a parameter @@ -2567,13 +2584,32 @@ TreeTransform::TransformFunctionProtoType(TypeLocBuilder &TLB, QualType OldType = T->getArgType(i); NewType = getDerived().TransformType(OldType); if (NewType.isNull()) - return QualType(); + return true; } - ParamTypes.push_back(NewType); - ParamDecls.push_back(NewParm); + PTypes.push_back(NewType); + PVars.push_back(NewParm); } + return false; +} + +template +QualType +TreeTransform::TransformFunctionProtoType(TypeLocBuilder &TLB, + FunctionProtoTypeLoc TL, + QualType ObjectType) { + FunctionProtoType *T = TL.getTypePtr(); + QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc()); + if (ResultType.isNull()) + return QualType(); + + // Transform the parameters. + llvm::SmallVector ParamTypes; + llvm::SmallVector ParamDecls; + if (getDerived().TransformFunctionTypeParams(TL, ParamTypes, ParamDecls)) + return QualType(); + QualType Result = TL.getType(); if (getDerived().AlwaysRebuild() || ResultType != T->getResultType() || -- cgit v1.2.3