From c21c7e9c2cded68f91be15be6847c9649242dc17 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 25 Jan 2011 19:13:18 +0000 Subject: [PATCH] Teach TemplateSpecializationTypeLoc::initializeArgLocs() to actually generate meaningful [*] template argument location information. [*] Well, as meaningful as possible, given that this entire code path is a hack for when we've lost type-source information. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124211 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/TypeLoc.h | 53 +++++++++++++++++-------------------- lib/AST/ASTContext.cpp | 2 +- lib/AST/TypeLoc.cpp | 40 ++++++++++++++++++++++++++-- lib/Sema/SemaTemplate.cpp | 6 +++-- lib/Sema/SemaType.cpp | 14 +++++----- lib/Sema/TreeTransform.h | 6 ++--- 6 files changed, 78 insertions(+), 43 deletions(-) diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index 9a771cbeb8..8af6bbd053 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -20,6 +20,7 @@ #include "clang/Basic/Specifiers.h" namespace clang { + class ASTContext; class ParmVarDecl; class TypeSourceInfo; class UnqualTypeLoc; @@ -126,8 +127,8 @@ public: /// /// This method exists to provide a simple transition for code that /// relies on location-less types. - void initialize(SourceLocation Loc) const { - initializeImpl(*this, Loc); + void initialize(ASTContext &Context, SourceLocation Loc) const { + initializeImpl(Context, *this, Loc); } /// \brief Initializes this by copying its information from another @@ -158,7 +159,7 @@ public: static bool classof(const TypeLoc *TL) { return true; } private: - static void initializeImpl(TypeLoc TL, SourceLocation Loc); + static void initializeImpl(ASTContext &Context, TypeLoc TL, SourceLocation Loc); static TypeLoc getNextTypeLocImpl(TypeLoc TL); static TypeLoc IgnoreParensImpl(TypeLoc TL); static SourceRange getLocalSourceRangeImpl(TypeLoc TL); @@ -207,7 +208,7 @@ public: /// Initializes the local data of this type source info block to /// provide no information. - void initializeLocal(SourceLocation Loc) { + void initializeLocal(ASTContext &Context, SourceLocation Loc) { // do nothing } @@ -407,7 +408,7 @@ public: SourceRange getLocalSourceRange() const { return SourceRange(getNameLoc(), getNameLoc()); } - void initializeLocal(SourceLocation Loc) { + void initializeLocal(ASTContext &Context, SourceLocation Loc) { setNameLoc(Loc); } @@ -508,7 +509,7 @@ public: getWrittenBuiltinSpecs().ModeAttr = written; } - void initializeLocal(SourceLocation Loc) { + void initializeLocal(ASTContext &Context, SourceLocation Loc) { setBuiltinLoc(Loc); if (needsExtraLocalData()) { WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs(); @@ -707,7 +708,7 @@ public: return range; } - void initializeLocal(SourceLocation loc) { + void initializeLocal(ASTContext &Context, SourceLocation loc) { setAttrNameLoc(loc); if (hasAttrExprOperand()) { setAttrOperandParensRange(SourceRange(loc)); @@ -793,7 +794,7 @@ public: return SourceRange(getLAngleLoc(), getRAngleLoc()); } - void initializeLocal(SourceLocation Loc) { + void initializeLocal(ASTContext &Context, SourceLocation Loc) { setHasBaseTypeAsWritten(true); setLAngleLoc(Loc); setRAngleLoc(Loc); @@ -837,7 +838,7 @@ public: return SourceRange(getNameLoc()); } - void initializeLocal(SourceLocation Loc) { + void initializeLocal(ASTContext &Context, SourceLocation Loc) { setNameLoc(Loc); } }; @@ -868,7 +869,7 @@ public: return SourceRange(getLParenLoc(), getRParenLoc()); } - void initializeLocal(SourceLocation Loc) { + void initializeLocal(ASTContext &Context, SourceLocation Loc) { setLParenLoc(Loc); setRParenLoc(Loc); } @@ -907,7 +908,7 @@ public: return SourceRange(getSigilLoc(), getSigilLoc()); } - void initializeLocal(SourceLocation Loc) { + void initializeLocal(ASTContext &Context, SourceLocation Loc) { setSigilLoc(Loc); } @@ -1058,7 +1059,7 @@ public: return SourceRange(getLParenLoc(), getRParenLoc()); } - void initializeLocal(SourceLocation Loc) { + void initializeLocal(ASTContext &Context, SourceLocation Loc) { setLParenLoc(Loc); setRParenLoc(Loc); setTrailingReturn(false); @@ -1132,7 +1133,7 @@ public: return SourceRange(getLBracketLoc(), getRBracketLoc()); } - void initializeLocal(SourceLocation Loc) { + void initializeLocal(ASTContext &Context, SourceLocation Loc) { setLBracketLoc(Loc); setRBracketLoc(Loc); setSizeExpr(NULL); @@ -1234,24 +1235,18 @@ public: return SourceRange(getTemplateNameLoc(), getRAngleLoc()); } - void initializeLocal(SourceLocation Loc) { + void initializeLocal(ASTContext &Context, SourceLocation Loc) { setLAngleLoc(Loc); setRAngleLoc(Loc); setTemplateNameLoc(Loc); - initializeArgLocs(getNumArgs(), getTypePtr()->getArgs(), + initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(), getArgInfos(), Loc); } - static void initializeArgLocs(unsigned NumArgs, + static void initializeArgLocs(ASTContext &Context, unsigned NumArgs, const TemplateArgument *Args, TemplateArgumentLocInfo *ArgInfos, - SourceLocation Loc) { - for (unsigned i = 0, e = NumArgs; i != e; ++i) { - // FIXME: We can generate better location info here for type arguments, - // template template arguments, and template template pack expansions (?). - ArgInfos[i] = TemplateArgumentLocInfo(); - } - } + SourceLocation Loc); unsigned getExtraLocalDataSize() const { return getNumArgs() * sizeof(TemplateArgumentLocInfo); @@ -1346,7 +1341,7 @@ public: return SourceRange(getTypeofLoc(), getRParenLoc()); } - void initializeLocal(SourceLocation Loc) { + void initializeLocal(ASTContext &Context, SourceLocation Loc) { setTypeofLoc(Loc); setLParenLoc(Loc); setRParenLoc(Loc); @@ -1420,7 +1415,7 @@ public: return getQualifierRange(); } - void initializeLocal(SourceLocation Loc) { + void initializeLocal(ASTContext &Context, SourceLocation Loc) { setKeywordLoc(Loc); setQualifierRange(SourceRange(Loc)); } @@ -1485,7 +1480,7 @@ public: memcpy(Data, Loc.Data, size); } - void initializeLocal(SourceLocation Loc) { + void initializeLocal(ASTContext &Context, SourceLocation Loc) { setKeywordLoc(Loc); setQualifierRange(SourceRange(Loc)); setNameLoc(Loc); @@ -1569,13 +1564,13 @@ public: memcpy(Data, Loc.Data, size); } - void initializeLocal(SourceLocation Loc) { + void initializeLocal(ASTContext &Context, SourceLocation Loc) { setKeywordLoc(Loc); setQualifierRange(SourceRange(Loc)); setNameLoc(Loc); setLAngleLoc(Loc); setRAngleLoc(Loc); - TemplateSpecializationTypeLoc::initializeArgLocs(getNumArgs(), + TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(), getArgInfos(), Loc); } @@ -1611,7 +1606,7 @@ public: return SourceRange(getEllipsisLoc(), getEllipsisLoc()); } - void initializeLocal(SourceLocation Loc) { + void initializeLocal(ASTContext &Context, SourceLocation Loc) { setEllipsisLoc(Loc); } diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 043d56a98d..1622d3cfa4 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1127,7 +1127,7 @@ TypeSourceInfo *ASTContext::CreateTypeSourceInfo(QualType T, TypeSourceInfo *ASTContext::getTrivialTypeSourceInfo(QualType T, SourceLocation L) const { TypeSourceInfo *DI = CreateTypeSourceInfo(T); - DI->getTypeLoc().initialize(L); + DI->getTypeLoc().initialize(const_cast(*this), L); return DI; } diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp index 08fe267b1d..0680acb1c5 100644 --- a/lib/AST/TypeLoc.cpp +++ b/lib/AST/TypeLoc.cpp @@ -77,14 +77,15 @@ TypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) { /// \brief Initializes a type location, and all of its children /// recursively, as if the entire tree had been written in the /// given location. -void TypeLoc::initializeImpl(TypeLoc TL, SourceLocation Loc) { +void TypeLoc::initializeImpl(ASTContext &Context, TypeLoc TL, + SourceLocation Loc) { while (true) { switch (TL.getTypeLocClass()) { #define ABSTRACT_TYPELOC(CLASS, PARENT) #define TYPELOC(CLASS, PARENT) \ case CLASS: { \ CLASS##TypeLoc TLCasted = cast(TL); \ - TLCasted.initializeLocal(Loc); \ + TLCasted.initializeLocal(Context, Loc); \ TL = TLCasted.getNextTypeLoc(); \ if (!TL) return; \ continue; \ @@ -229,3 +230,38 @@ TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) { TL = PTL->getInnerLoc(); return TL; } + +void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context, + unsigned NumArgs, + const TemplateArgument *Args, + TemplateArgumentLocInfo *ArgInfos, + SourceLocation Loc) { + for (unsigned i = 0, e = NumArgs; i != e; ++i) { + switch (Args[i].getKind()) { + case TemplateArgument::Null: + case TemplateArgument::Declaration: + case TemplateArgument::Integral: + case TemplateArgument::Pack: + case TemplateArgument::Expression: + // FIXME: Can we do better for declarations and integral values? + ArgInfos[i] = TemplateArgumentLocInfo(); + break; + + case TemplateArgument::Type: + ArgInfos[i] = TemplateArgumentLocInfo( + Context.getTrivialTypeSourceInfo(Args[i].getAsType(), + Loc)); + break; + + case TemplateArgument::Template: + ArgInfos[i] = TemplateArgumentLocInfo(SourceRange(Loc), Loc, + SourceLocation()); + break; + + case TemplateArgument::TemplateExpansion: + ArgInfos[i] = TemplateArgumentLocInfo(SourceRange(Loc), Loc, Loc); + break; + } + } +} + diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 2d2c3ea672..78f8d5e05a 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -5901,7 +5901,8 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, if (InnerTSI) Builder.pushFullCopy(InnerTSI->getTypeLoc()); else - Builder.push(T).initialize(TemplateLoc); + Builder.push(T).initialize(Context, + TemplateLoc); /* Note: NNS already embedded in template specialization type T. */ T = Context.getElaboratedType(ETK_Typename, /*NNS=*/0, T); @@ -5937,7 +5938,8 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, for (unsigned I = 0, E = TST->getNumArgs(); I != E; ++I) TL.setArgLocInfo(I, TSTL.getArgLocInfo(I)); } else { - TL.initializeLocal(SourceLocation()); + // FIXME: Poor source-location information here. + TL.initializeLocal(Context, TemplateLoc); } TL.setKeywordLoc(TypenameLoc); TL.setQualifierRange(SS.getRange()); diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 40d3734836..c8f7545602 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1972,10 +1972,12 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S, namespace { class TypeSpecLocFiller : public TypeLocVisitor { + ASTContext &Context; const DeclSpec &DS; public: - TypeSpecLocFiller(const DeclSpec &DS) : DS(DS) {} + TypeSpecLocFiller(ASTContext &Context, const DeclSpec &DS) + : Context(Context), DS(DS) {} void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { Visit(TL.getUnqualifiedLoc()); @@ -1990,7 +1992,7 @@ namespace { // Handle the base type, which might not have been written explicitly. if (DS.getTypeSpecType() == DeclSpec::TST_unspecified) { TL.setHasBaseTypeAsWritten(false); - TL.getBaseLoc().initialize(SourceLocation()); + TL.getBaseLoc().initialize(Context, SourceLocation()); } else { TL.setHasBaseTypeAsWritten(true); Visit(TL.getBaseLoc()); @@ -2021,7 +2023,7 @@ namespace { // If we got no declarator info from previous Sema routines, // just fill with the typespec loc. if (!TInfo) { - TL.initialize(DS.getTypeSpecTypeLoc()); + TL.initialize(Context, DS.getTypeSpecTypeLoc()); return; } @@ -2114,7 +2116,7 @@ namespace { return; } } - TL.initializeLocal(SourceLocation()); + TL.initializeLocal(Context, SourceLocation()); TL.setKeywordLoc(Keyword != ETK_None ? DS.getTypeSpecTypeLoc() : SourceLocation()); @@ -2126,7 +2128,7 @@ namespace { void VisitTypeLoc(TypeLoc TL) { // FIXME: add other typespec types and change this to an assert. - TL.initialize(DS.getTypeSpecTypeLoc()); + TL.initialize(Context, DS.getTypeSpecTypeLoc()); } }; @@ -2231,7 +2233,7 @@ Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T, assert(TL.getFullDataSize() == CurrTL.getFullDataSize()); memcpy(CurrTL.getOpaqueData(), TL.getOpaqueData(), TL.getFullDataSize()); } else { - TypeSpecLocFiller(D.getDeclSpec()).Visit(CurrTL); + TypeSpecLocFiller(Context, D.getDeclSpec()).Visit(CurrTL); } return TInfo; diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 654bf90e87..04c45b8da7 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -2980,8 +2980,8 @@ QualType TreeTransform::TransformType(QualType T) { // Temporary workaround. All of these transformations should // eventually turn into transformations on TypeLocs. - TypeSourceInfo *DI = getSema().Context.CreateTypeSourceInfo(T); - DI->getTypeLoc().initialize(getDerived().getBaseLocation()); + TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T, + getDerived().getBaseLocation()); TypeSourceInfo *NewDI = getDerived().TransformType(DI); @@ -3073,7 +3073,7 @@ TreeTransform::TransformTypeInObjectScope(QualType T, return T; TypeSourceInfo *TSI = - SemaRef.Context.getTrivialTypeSourceInfo(T, getBaseLocation()); + SemaRef.Context.getTrivialTypeSourceInfo(T, getDerived().getBaseLocation()); TSI = getDerived().TransformTypeInObjectScope(TSI, ObjectType, UnqualLookup, Prefix); -- 2.40.0