diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2012-06-07 15:09:51 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2012-06-07 15:09:51 +0000 |
commit | 6003ad584890456e7a3b3a970413a9f2e1d921f2 (patch) | |
tree | 37a0f49d157d59c199e7eb8cefdd1c81d2fc8b91 /clang/lib | |
parent | 29aaccda13ead82c67c204acca0d125f1d5538a7 (diff) | |
download | bcm5719-llvm-6003ad584890456e7a3b3a970413a9f2e1d921f2.tar.gz bcm5719-llvm-6003ad584890456e7a3b3a970413a9f2e1d921f2.zip |
Plug a long standing memory leak in TemplateArgument.
The integral APSInt value is now stored in a decomposed form and the backing
store for large values is allocated via the ASTContext. This way its not
leaked as TemplateArguments are never destructed when they are allocated in
the ASTContext. Since the integral data is immutable it is now shared between
instances, making copying TemplateArguments a trivial operation.
Currently getting the integral data out of a TemplateArgument requires creating
a new APSInt object. This is cheap when the value is small but can be expensive
if it's not. If this turns out to be an issue a more efficient accessor could
be added.
llvm-svn: 158150
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 3 | ||||
-rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 4 | ||||
-rw-r--r-- | clang/lib/AST/DumpXML.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/TemplateBase.cpp | 32 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 2 |
14 files changed, 49 insertions, 30 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 164813b7c35..bd68d832500 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -3336,8 +3336,7 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const { Arg.getNumTemplateExpansions()); case TemplateArgument::Integral: - return TemplateArgument(*Arg.getAsIntegral(), - getCanonicalType(Arg.getIntegralType())); + return TemplateArgument(Arg, getCanonicalType(Arg.getIntegralType())); case TemplateArgument::Type: return TemplateArgument(getCanonicalType(Arg.getAsType())); diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 417f3cff58b..9f016fe9bbb 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -322,7 +322,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, Arg2.getIntegralType())) return false; - return IsSameValue(*Arg1.getAsIntegral(), *Arg2.getAsIntegral()); + return IsSameValue(Arg1.getAsIntegral(), Arg2.getAsIntegral()); case TemplateArgument::Declaration: if (!Arg1.getAsDecl() || !Arg2.getAsDecl()) @@ -1992,7 +1992,7 @@ ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) { QualType ToType = Importer.Import(From.getIntegralType()); if (ToType.isNull()) return TemplateArgument(); - return TemplateArgument(*From.getAsIntegral(), ToType); + return TemplateArgument(From, ToType); } case TemplateArgument::Declaration: diff --git a/clang/lib/AST/DumpXML.cpp b/clang/lib/AST/DumpXML.cpp index 4c7cd8a6793..4df692d9a51 100644 --- a/clang/lib/AST/DumpXML.cpp +++ b/clang/lib/AST/DumpXML.cpp @@ -326,7 +326,7 @@ struct XMLDumper : public XMLDeclVisitor<XMLDumper>, } case TemplateArgument::Integral: { push("integer"); - setInteger("value", *A.getAsIntegral()); + setInteger("value", A.getAsIntegral()); completeAttrs(); pop(); break; diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index e974ade6f60..7c7a5e5de38 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -3132,7 +3132,7 @@ void CXXNameMangler::mangleTemplateArg(const NamedDecl *P, break; } case TemplateArgument::Integral: - mangleIntegerLiteral(A.getIntegralType(), *A.getAsIntegral()); + mangleIntegerLiteral(A.getIntegralType(), A.getAsIntegral()); break; case TemplateArgument::Declaration: { assert(P && "Missing template parameter for declaration argument"); diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 59848817028..b0d9316fe5c 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -638,7 +638,7 @@ MicrosoftCXXNameMangler::mangleTemplateArgs(const TemplateArgument *TemplateArgs mangleType(TA.getAsType()); break; case TemplateArgument::Integral: - mangleIntegerLiteral(TA.getIntegralType(), *TA.getAsIntegral()); + mangleIntegerLiteral(TA.getIntegralType(), TA.getAsIntegral()); break; default: { // Issue a diagnostic. diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 7309e7c889a..2bd4d769e79 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1275,7 +1275,7 @@ void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) { const TemplateArgument &Pack = Args->get(0); for (TemplateArgument::pack_iterator I = Pack.pack_begin(), E = Pack.pack_end(); I != E; ++I) { - char C = (char)I->getAsIntegral()->getZExtValue(); + char C = (char)I->getAsIntegral().getZExtValue(); OS << C; } break; diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index e6b378e16f0..72b979d4c2f 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -1161,7 +1161,7 @@ void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) { break; case TemplateArgument::Integral: - Arg.getAsIntegral()->Profile(ID); + Arg.getAsIntegral().Profile(ID); VisitType(Arg.getIntegralType()); break; diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp index 531e03e302b..284c1b5baae 100644 --- a/clang/lib/AST/TemplateBase.cpp +++ b/clang/lib/AST/TemplateBase.cpp @@ -36,17 +36,17 @@ using namespace clang; static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out) { const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr(); - const llvm::APSInt *Val = TemplArg.getAsIntegral(); + const llvm::APSInt &Val = TemplArg.getAsIntegral(); if (T->isBooleanType()) { - Out << (Val->getBoolValue() ? "true" : "false"); + Out << (Val.getBoolValue() ? "true" : "false"); } else if (T->isCharType()) { - const char Ch = Val->getZExtValue(); + const char Ch = Val.getZExtValue(); Out << ((Ch == '\'') ? "'\\" : "'"); Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true); Out << "'"; } else { - Out << Val->toString(10); + Out << Val; } } @@ -54,6 +54,24 @@ static void printIntegral(const TemplateArgument &TemplArg, // TemplateArgument Implementation //===----------------------------------------------------------------------===// +TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, + QualType Type) + : Kind(Integral) { + // Copy the APSInt value into our decomposed form. + Integer.BitWidth = Value.getBitWidth(); + Integer.IsUnsigned = Value.isUnsigned(); + // If the value is large, we have to get additional memory from the ASTContext + if (Integer.BitWidth > 64) { + void *Mem = Ctx.Allocate(Integer.BitWidth / 8); + std::memcpy(Mem, Value.getRawData(), Integer.BitWidth / 8); + Integer.pVal = static_cast<uint64_t *>(Mem); + } else { + Integer.VAL = Value.getZExtValue(); + } + + Integer.Type = Type.getAsOpaquePtr(); +} + TemplateArgument TemplateArgument::CreatePackCopy(ASTContext &Context, const TemplateArgument *Args, unsigned NumArgs) { @@ -246,7 +264,7 @@ void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID, } case Integral: - getAsIntegral()->Profile(ID); + getAsIntegral().Profile(ID); getIntegralType().Profile(ID); break; @@ -275,7 +293,7 @@ bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const { case Integral: return getIntegralType() == Other.getIntegralType() && - *getAsIntegral() == *Other.getAsIntegral(); + getAsIntegral() == Other.getAsIntegral(); case Pack: if (Args.NumArgs != Other.Args.NumArgs) return false; @@ -498,7 +516,7 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, return DB << "nullptr"; case TemplateArgument::Integral: - return DB << Arg.getAsIntegral()->toString(10); + return DB << Arg.getAsIntegral().toString(10); case TemplateArgument::Template: return DB << Arg.getAsTemplate(); diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index beea777a978..8d28322c44c 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1086,7 +1086,7 @@ CollectTemplateParams(const TemplateParameterList *TPList, llvm::DIType TTy = getOrCreateType(TA.getIntegralType(), Unit); llvm::DITemplateValueParameter TVP = DBuilder.createTemplateValueParameter(TheCU, ND->getName(), TTy, - TA.getAsIntegral()->getZExtValue()); + TA.getAsIntegral().getZExtValue()); TemplateParams.push_back(TVP); } } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 9f0378ac0ef..d2377f59056 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2605,7 +2605,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { llvm::APSInt Value(CharBits, CharIsUnsigned); for (unsigned I = 0, N = Literal.getUDSuffixOffset(); I != N; ++I) { Value = ThisTokBegin[I]; - TemplateArgument Arg(Value, Context.CharTy); + TemplateArgument Arg(Context, Value, Context.CharTy); TemplateArgumentLocInfo ArgInfo; ExplicitArgs.addArgument(TemplateArgumentLoc(Arg, ArgInfo)); } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 002b0b174e5..dccb4b6a61f 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -4125,7 +4125,8 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, IntegerType = Enum->getDecl()->getIntegerType(); Value = Value.extOrTrunc(Context.getTypeSize(IntegerType)); - Converted = TemplateArgument(Value, Context.getCanonicalType(ParamType)); + Converted = TemplateArgument(Context, Value, + Context.getCanonicalType(ParamType)); return ArgResult; } @@ -4251,7 +4252,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, } } - Converted = TemplateArgument(Value, + Converted = TemplateArgument(Context, Value, ParamType->isEnumeralType() ? Context.getCanonicalType(ParamType) : IntegerType); @@ -4569,13 +4570,13 @@ Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg, Kind = CharacterLiteral::Ascii; return Owned(new (Context) CharacterLiteral( - Arg.getAsIntegral()->getZExtValue(), + Arg.getAsIntegral().getZExtValue(), Kind, T, Loc)); } if (T->isBooleanType()) return Owned(new (Context) CXXBoolLiteralExpr( - Arg.getAsIntegral()->getBoolValue(), + Arg.getAsIntegral().getBoolValue(), T, Loc)); if (T->isNullPtrType()) @@ -4590,7 +4591,7 @@ Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg, else BT = T; - Expr *E = IntegerLiteral::Create(Context, *Arg.getAsIntegral(), BT, Loc); + Expr *E = IntegerLiteral::Create(Context, Arg.getAsIntegral(), BT, Loc); if (T->isEnumeralType()) { // FIXME: This is a hack. We need a better way to handle substituted // non-type template parameters. diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index e6f2b2d649a..78a860c53da 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -193,7 +193,7 @@ checkDeducedTemplateArguments(ASTContext &Context, if (Y.getKind() == TemplateArgument::Expression || Y.getKind() == TemplateArgument::Declaration || (Y.getKind() == TemplateArgument::Integral && - hasSameExtendedValue(*X.getAsIntegral(), *Y.getAsIntegral()))) + hasSameExtendedValue(X.getAsIntegral(), Y.getAsIntegral()))) return DeducedTemplateArgument(X, X.wasDeducedFromArrayBound() && Y.wasDeducedFromArrayBound()); @@ -293,7 +293,8 @@ DeduceNonTypeTemplateArgument(Sema &S, assert(NTTP->getDepth() == 0 && "Cannot deduce non-type template argument with depth > 0"); - DeducedTemplateArgument NewDeduced(Value, ValueType, DeducedFromArrayBound); + DeducedTemplateArgument NewDeduced(S.Context, Value, ValueType, + DeducedFromArrayBound); DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context, Deduced[NTTP->getIndex()], NewDeduced); @@ -1595,7 +1596,7 @@ DeduceTemplateArguments(Sema &S, case TemplateArgument::Integral: if (Arg.getKind() == TemplateArgument::Integral) { - if (hasSameExtendedValue(*Param.getAsIntegral(), *Arg.getAsIntegral())) + if (hasSameExtendedValue(Param.getAsIntegral(), Arg.getAsIntegral())) return Sema::TDK_Success; Info.FirstArg = Param; @@ -1618,7 +1619,7 @@ DeduceTemplateArguments(Sema &S, = getDeducedParameterFromExpr(Param.getAsExpr())) { if (Arg.getKind() == TemplateArgument::Integral) return DeduceNonTypeTemplateArgument(S, NTTP, - *Arg.getAsIntegral(), + Arg.getAsIntegral(), Arg.getIntegralType(), /*ArrayBound=*/false, Info, Deduced); @@ -1867,7 +1868,7 @@ static bool isSameTemplateArg(ASTContext &Context, Y.getAsTemplateOrTemplatePattern()).getAsVoidPointer(); case TemplateArgument::Integral: - return *X.getAsIntegral() == *Y.getAsIntegral(); + return X.getAsIntegral() == Y.getAsIntegral(); case TemplateArgument::Expression: { llvm::FoldingSetNodeID XID, YID; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index a9092a43aa1..3b59163d24f 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -5905,7 +5905,7 @@ ASTReader::ReadTemplateArgument(ModuleFile &F, case TemplateArgument::Integral: { llvm::APSInt Value = ReadAPSInt(Record, Idx); QualType T = readType(F, Record, Idx); - return TemplateArgument(Value, T); + return TemplateArgument(Context, Value, T); } case TemplateArgument::Template: return TemplateArgument(ReadTemplateName(F, Record, Idx)); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index edef1c026f3..0eb2f1675be 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -4147,7 +4147,7 @@ void ASTWriter::AddTemplateArgument(const TemplateArgument &Arg, AddDeclRef(Arg.getAsDecl(), Record); break; case TemplateArgument::Integral: - AddAPSInt(*Arg.getAsIntegral(), Record); + AddAPSInt(Arg.getAsIntegral(), Record); AddTypeRef(Arg.getIntegralType(), Record); break; case TemplateArgument::Template: |