summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2012-06-07 15:09:51 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2012-06-07 15:09:51 +0000
commit6003ad584890456e7a3b3a970413a9f2e1d921f2 (patch)
tree37a0f49d157d59c199e7eb8cefdd1c81d2fc8b91 /clang/lib
parent29aaccda13ead82c67c204acca0d125f1d5538a7 (diff)
downloadbcm5719-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.cpp3
-rw-r--r--clang/lib/AST/ASTImporter.cpp4
-rw-r--r--clang/lib/AST/DumpXML.cpp2
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp2
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp2
-rw-r--r--clang/lib/AST/StmtPrinter.cpp2
-rw-r--r--clang/lib/AST/StmtProfile.cpp2
-rw-r--r--clang/lib/AST/TemplateBase.cpp32
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp2
-rw-r--r--clang/lib/Sema/SemaExpr.cpp2
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp11
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp11
-rw-r--r--clang/lib/Serialization/ASTReader.cpp2
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp2
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:
OpenPOWER on IntegriCloud