From: Eli Friedman Date: Thu, 20 Jun 2013 04:11:21 +0000 (+0000) Subject: Fix one place I missed that was memcpy'ing TypeLocs in a way that messes X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=850cf510b8e310a99344c29731f0b68e096a8658;p=clang Fix one place I missed that was memcpy'ing TypeLocs in a way that messes up alignment. Fixes utilities/tuple/tuple.tuple/tuple.creation/tuple_cat.pass.cpp from the libc++ testsuite. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184397 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index 70b934f36c..6441312244 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -494,17 +494,6 @@ public: assert(Argument.getKind() == TemplateArgument::TemplateExpansion); return LocInfo.getTemplateEllipsisLoc(); } - - /// \brief When the template argument is a pack expansion, returns - /// the pattern of the pack expansion. - /// - /// \param Ellipsis Will be set to the location of the ellipsis. - /// - /// \param NumExpansions Will be set to the number of expansions that will - /// be generated from this pack expansion, if known a priori. - TemplateArgumentLoc getPackExpansionPattern(SourceLocation &Ellipsis, - Optional &NumExpansions, - ASTContext &Context) const; }; /// A convenient class for passing around template argument diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 4f6725f9af..6b719c9b21 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -5591,6 +5591,19 @@ public: /// false otherwise. bool containsUnexpandedParameterPacks(Declarator &D); + /// \brief Returns the pattern of the pack expansion for a template argument. + /// + /// \param OrigLoc The template argument to expand. + /// + /// \param Ellipsis Will be set to the location of the ellipsis. + /// + /// \param NumExpansions Will be set to the number of expansions that will + /// be generated from this pack expansion, if known a priori. + TemplateArgumentLoc getTemplateArgumentPackExpansionPattern( + TemplateArgumentLoc OrigLoc, + SourceLocation &Ellipsis, + Optional &NumExpansions) const; + //===--------------------------------------------------------------------===// // C++ Template Argument Deduction (C++ [temp.deduct]) //===--------------------------------------------------------------------===// diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp index c3e2c4a7bb..2a9ffd68a3 100644 --- a/lib/AST/TemplateBase.cpp +++ b/lib/AST/TemplateBase.cpp @@ -450,68 +450,6 @@ SourceRange TemplateArgumentLoc::getSourceRange() const { llvm_unreachable("Invalid TemplateArgument Kind!"); } -TemplateArgumentLoc TemplateArgumentLoc::getPackExpansionPattern( - SourceLocation &Ellipsis, Optional &NumExpansions, - ASTContext &Context) const { - assert(Argument.isPackExpansion()); - - switch (Argument.getKind()) { - case TemplateArgument::Type: { - // FIXME: We shouldn't ever have to worry about missing - // type-source info! - TypeSourceInfo *ExpansionTSInfo = getTypeSourceInfo(); - if (!ExpansionTSInfo) - ExpansionTSInfo = Context.getTrivialTypeSourceInfo( - getArgument().getAsType(), - Ellipsis); - PackExpansionTypeLoc Expansion = - ExpansionTSInfo->getTypeLoc().castAs(); - Ellipsis = Expansion.getEllipsisLoc(); - - TypeLoc Pattern = Expansion.getPatternLoc(); - NumExpansions = Expansion.getTypePtr()->getNumExpansions(); - - // FIXME: This is horrible. We know where the source location data is for - // the pattern, and we have the pattern's type, but we are forced to copy - // them into an ASTContext because TypeSourceInfo bundles them together - // and TemplateArgumentLoc traffics in TypeSourceInfo pointers. - TypeSourceInfo *PatternTSInfo - = Context.CreateTypeSourceInfo(Pattern.getType(), - Pattern.getFullDataSize()); - memcpy(PatternTSInfo->getTypeLoc().getOpaqueData(), - Pattern.getOpaqueData(), Pattern.getFullDataSize()); - return TemplateArgumentLoc(TemplateArgument(Pattern.getType()), - PatternTSInfo); - } - - case TemplateArgument::Expression: { - PackExpansionExpr *Expansion - = cast(Argument.getAsExpr()); - Expr *Pattern = Expansion->getPattern(); - Ellipsis = Expansion->getEllipsisLoc(); - NumExpansions = Expansion->getNumExpansions(); - return TemplateArgumentLoc(Pattern, Pattern); - } - - case TemplateArgument::TemplateExpansion: - Ellipsis = getTemplateEllipsisLoc(); - NumExpansions = Argument.getNumTemplateExpansions(); - return TemplateArgumentLoc(Argument.getPackExpansionPattern(), - getTemplateQualifierLoc(), - getTemplateNameLoc()); - - case TemplateArgument::Declaration: - case TemplateArgument::NullPtr: - case TemplateArgument::Template: - case TemplateArgument::Integral: - case TemplateArgument::Pack: - case TemplateArgument::Null: - return TemplateArgumentLoc(); - } - - llvm_unreachable("Invalid TemplateArgument Kind!"); -} - const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, const TemplateArgument &Arg) { switch (Arg.getKind()) { diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index cb6f4c19de..6298332dc1 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -849,3 +849,63 @@ ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, return new (Context) SizeOfPackExpr(Context.getSizeType(), OpLoc, ParameterPack, NameLoc, RParenLoc); } + +TemplateArgumentLoc +Sema::getTemplateArgumentPackExpansionPattern( + TemplateArgumentLoc OrigLoc, + SourceLocation &Ellipsis, Optional &NumExpansions) const { + const TemplateArgument &Argument = OrigLoc.getArgument(); + assert(Argument.isPackExpansion()); + switch (Argument.getKind()) { + case TemplateArgument::Type: { + // FIXME: We shouldn't ever have to worry about missing + // type-source info! + TypeSourceInfo *ExpansionTSInfo = OrigLoc.getTypeSourceInfo(); + if (!ExpansionTSInfo) + ExpansionTSInfo = Context.getTrivialTypeSourceInfo(Argument.getAsType(), + Ellipsis); + PackExpansionTypeLoc Expansion = + ExpansionTSInfo->getTypeLoc().castAs(); + Ellipsis = Expansion.getEllipsisLoc(); + + TypeLoc Pattern = Expansion.getPatternLoc(); + NumExpansions = Expansion.getTypePtr()->getNumExpansions(); + + // We need to copy the TypeLoc because TemplateArgumentLocs store a + // TypeSourceInfo. + // FIXME: Find some way to avoid the copy? + TypeLocBuilder TLB; + TLB.pushFullCopy(Pattern); + TypeSourceInfo *PatternTSInfo = + TLB.getTypeSourceInfo(Context, Pattern.getType()); + return TemplateArgumentLoc(TemplateArgument(Pattern.getType()), + PatternTSInfo); + } + + case TemplateArgument::Expression: { + PackExpansionExpr *Expansion + = cast(Argument.getAsExpr()); + Expr *Pattern = Expansion->getPattern(); + Ellipsis = Expansion->getEllipsisLoc(); + NumExpansions = Expansion->getNumExpansions(); + return TemplateArgumentLoc(Pattern, Pattern); + } + + case TemplateArgument::TemplateExpansion: + Ellipsis = OrigLoc.getTemplateEllipsisLoc(); + NumExpansions = Argument.getNumTemplateExpansions(); + return TemplateArgumentLoc(Argument.getPackExpansionPattern(), + OrigLoc.getTemplateQualifierLoc(), + OrigLoc.getTemplateNameLoc()); + + case TemplateArgument::Declaration: + case TemplateArgument::NullPtr: + case TemplateArgument::Template: + case TemplateArgument::Integral: + case TemplateArgument::Pack: + case TemplateArgument::Null: + return TemplateArgumentLoc(); + } + + llvm_unreachable("Invalid TemplateArgument Kind!"); +} diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 1fd206bbc2..86624c580e 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -3233,8 +3233,8 @@ bool TreeTransform::TransformTemplateArguments(InputIterator First, SourceLocation Ellipsis; Optional OrigNumExpansions; TemplateArgumentLoc Pattern - = In.getPackExpansionPattern(Ellipsis, OrigNumExpansions, - getSema().Context); + = getSema().getTemplateArgumentPackExpansionPattern( + In, Ellipsis, OrigNumExpansions); SmallVector Unexpanded; getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);