From 5b0f752655cc94b970113235110b56a722eb40d4 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Sat, 14 Mar 2009 00:03:48 +0000 Subject: [PATCH] Make sure that the canonical representation of integral template arguments uses the bitwidth and signedness of the template parameter git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66990 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/DeclTemplate.h | 28 ++++++++++++++-------------- lib/Sema/SemaTemplate.cpp | 9 +++++---- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 17e5ad0b67..68d93ccc7f 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -15,7 +15,7 @@ #define LLVM_CLANG_AST_DECLTEMPLATE_H #include "clang/AST/DeclCXX.h" -#include "llvm/ADT/APInt.h" +#include "llvm/ADT/APSInt.h" #include "llvm/ADT/FoldingSet.h" namespace clang { @@ -407,7 +407,7 @@ class TemplateArgument { union { uintptr_t TypeOrValue; struct { - char Value[sizeof(llvm::APInt)]; + char Value[sizeof(llvm::APSInt)]; void *Type; } Integer; }; @@ -423,7 +423,7 @@ public: Type = 0, /// The template argument is a declaration Declaration = 1, - /// The template argument is an integral value stored in an llvm::APInt. + /// The template argument is an integral value stored in an llvm::APSInt. Integral = 2, /// The template argument is a value- or type-dependent expression /// stored in an Expr*. @@ -449,10 +449,10 @@ public: } /// \brief Construct an integral constant template argument. - TemplateArgument(SourceLocation Loc, const llvm::APInt &Value, + TemplateArgument(SourceLocation Loc, const llvm::APSInt &Value, QualType Type) : Kind(Integral) { - new (Integer.Value) llvm::APInt(Value); + new (Integer.Value) llvm::APSInt(Value); Integer.Type = Type.getAsOpaquePtr(); StartLoc = Loc; } @@ -467,7 +467,7 @@ public: /// \brief Copy constructor for a template argument. TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) { if (Kind == Integral) { - new (Integer.Value) llvm::APInt(*Other.getAsIntegral()); + new (Integer.Value) llvm::APSInt(*Other.getAsIntegral()); Integer.Type = Other.Integer.Type; } else @@ -478,7 +478,7 @@ public: TemplateArgument& operator=(const TemplateArgument& Other) { // FIXME: Does not provide the strong guarantee for exception // safety. - using llvm::APInt; + using llvm::APSInt; if (Kind == Other.Kind && Kind == Integral) { // Copy integral values. @@ -487,12 +487,12 @@ public: } else { // Destroy the current integral value, if that's what we're holding. if (Kind == Integral) - getAsIntegral()->~APInt(); + getAsIntegral()->~APSInt(); Kind = Other.Kind; if (Other.Kind == Integral) { - new (Integer.Value) llvm::APInt(*Other.getAsIntegral()); + new (Integer.Value) llvm::APSInt(*Other.getAsIntegral()); Integer.Type = Other.Integer.Type; } else TypeOrValue = Other.TypeOrValue; @@ -503,10 +503,10 @@ public: } ~TemplateArgument() { - using llvm::APInt; + using llvm::APSInt; if (Kind == Integral) - getAsIntegral()->~APInt(); + getAsIntegral()->~APSInt(); } /// \brief Return the kind of stored template argument. @@ -529,13 +529,13 @@ public: } /// \brief Retrieve the template argument as an integral value. - llvm::APInt *getAsIntegral() { + llvm::APSInt *getAsIntegral() { if (Kind != Integral) return 0; - return reinterpret_cast(&Integer.Value[0]); + return reinterpret_cast(&Integer.Value[0]); } - const llvm::APInt *getAsIntegral() const { + const llvm::APSInt *getAsIntegral() const { return const_cast(this)->getAsIntegral(); } diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 3780259d43..142cc453f3 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -1283,11 +1283,12 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, return false; } - llvm::APInt CanonicalArg(Context.getTypeSize(IntegerType), 0, - IntegerType->isSignedIntegerType()); - CanonicalArg = Value; + unsigned ExpectedBits = Context.getTypeSize(IntegerType); + if (Value.getBitWidth() != ExpectedBits) + Value.extOrTrunc(ExpectedBits); + Value.setIsSigned(IntegerType->isSignedIntegerType()); - Converted->push_back(TemplateArgument(StartLoc, CanonicalArg, + Converted->push_back(TemplateArgument(StartLoc, Value, Context.getCanonicalType(IntegerType))); } -- 2.40.0