[cfe-commits] r118385 - in /cfe/trunk: include/clang/AST/ include/clang/Basic/ include/clang/Sema/ lib/AST/ lib/CodeGen/ lib/Sema/ lib/Serialization/ test/SemaTemplate/ tools/libclang/
Douglas Gregor
dgregor at apple.com
Sun Nov 7 15:05:16 PST 2010
Author: dgregor
Date: Sun Nov 7 17:05:16 2010
New Revision: 118385
URL: http://llvm.org/viewvc/llvm-project?rev=118385&view=rev
Log:
Remove broken support for variadic templates, along with the various
abstractions (e.g., TemplateArgumentListBuilder) that were designed to
support variadic templates. Only a few remnants of variadic templates
remain, in the parser (parsing template type parameter packs), AST
(template type parameter pack bits and TemplateArgument::Pack), and
Sema; these are expected to be used in a future implementation of
variadic templates.
But don't get too excited about that happening now.
Removed:
cfe/trunk/test/SemaTemplate/variadic-class-template-1.cpp
cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp
cfe/trunk/test/SemaTemplate/variadic-parse.cpp
cfe/trunk/test/SemaTemplate/variadic-unsupported.cpp
Modified:
cfe/trunk/include/clang/AST/DeclTemplate.h
cfe/trunk/include/clang/AST/TemplateBase.h
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/include/clang/Sema/Template.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/lib/AST/DeclTemplate.cpp
cfe/trunk/lib/AST/TemplateBase.cpp
cfe/trunk/lib/AST/TypePrinter.cpp
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/lib/Sema/TreeTransform.h
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
cfe/trunk/tools/libclang/CIndex.cpp
Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Sun Nov 7 17:05:16 2010
@@ -85,7 +85,7 @@
return begin()[Idx];
}
- /// \btief Returns the minimum number of arguments needed to form a
+ /// \brief Returns the minimum number of arguments needed to form a
/// template specialization. This may be fewer than the number of
/// template parameters, if some of the parameters have default
/// arguments or if there is a parameter pack.
@@ -107,101 +107,57 @@
}
};
-/// \brief A helper class for making template argument lists.
-class TemplateArgumentListBuilder {
- TemplateArgument *StructuredArgs;
- unsigned MaxStructuredArgs;
- unsigned NumStructuredArgs;
-
- llvm::SmallVector<TemplateArgument, 4> FlatArgs;
- unsigned MaxFlatArgs;
- unsigned NumFlatArgs;
-
- bool AddingToPack;
- unsigned PackBeginIndex;
-
-public:
- TemplateArgumentListBuilder(const TemplateParameterList *Parameters,
- unsigned NumTemplateArgs)
- : StructuredArgs(0), MaxStructuredArgs(Parameters->size()),
- NumStructuredArgs(0), FlatArgs(0),
- MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
- AddingToPack(false), PackBeginIndex(0) { }
-
- void Append(const TemplateArgument &Arg);
- void BeginPack();
- void EndPack();
-
- unsigned flatSize() const { return FlatArgs.size(); }
- const TemplateArgument *getFlatArguments() const { return FlatArgs.data(); }
-
- unsigned structuredSize() const {
- // If we don't have any structured args, just reuse the flat size.
- if (!StructuredArgs)
- return flatSize();
-
- return NumStructuredArgs;
- }
- const TemplateArgument *getStructuredArguments() const {
- // If we don't have any structured args, just reuse the flat args.
- if (!StructuredArgs)
- return getFlatArguments();
-
- return StructuredArgs;
- }
-};
-
/// \brief A template argument list.
-///
-/// FIXME: In the future, this class will be extended to support
-/// variadic templates and member templates, which will make some of
-/// the function names below make more sense.
class TemplateArgumentList {
/// \brief The template argument list.
///
/// The integer value will be non-zero to indicate that this
/// template argument list does own the pointer.
- llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
+ llvm::PointerIntPair<const TemplateArgument *, 1> Arguments;
/// \brief The number of template arguments in this template
/// argument list.
- unsigned NumFlatArguments;
-
- llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
- unsigned NumStructuredArguments;
+ unsigned NumArguments;
TemplateArgumentList(const TemplateArgumentList &Other); // DO NOT IMPL
void operator=(const TemplateArgumentList &Other); // DO NOT IMPL
+
+ TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs,
+ bool Owned)
+ : Arguments(Args, Owned), NumArguments(NumArgs) { }
+
public:
- /// TemplateArgumentList - If this constructor is passed "true" for 'TakeArgs'
- /// it copies them into a locally new[]'d array. If passed "false", then it
- /// just references the array passed in. This is only safe if the builder
- /// outlives it, but saves a copy.
- TemplateArgumentList(ASTContext &Context,
- TemplateArgumentListBuilder &Builder,
- bool TakeArgs);
-
- /// TemplateArgumentList - It copies the template arguments into a locally
- /// new[]'d array.
- TemplateArgumentList(ASTContext &Context,
- const TemplateArgument *Args, unsigned NumArgs);
-
- /// Produces a shallow copy of the given template argument list. This
- /// assumes that the input argument list outlives it. This takes the list as
- /// a pointer to avoid looking like a copy constructor, since this really
- /// really isn't safe to use that way.
- explicit TemplateArgumentList(const TemplateArgumentList *Other);
-
- TemplateArgumentList() : NumFlatArguments(0), NumStructuredArguments(0) { }
-
- /// \brief Copies the template arguments into a locally new[]'d array.
- void init(ASTContext &Context,
- const TemplateArgument *Args, unsigned NumArgs);
+ /// \brief Type used to indicate that the template argument list itself is a
+ /// stack object. It does not own its template arguments.
+ enum OnStackType { OnStack };
+
+ /// \brief Create a new template argument list that copies the given set of
+ /// template arguments.
+ static TemplateArgumentList *CreateCopy(ASTContext &Context,
+ const TemplateArgument *Args,
+ unsigned NumArgs);
+
+ /// \brief Construct a new, temporary template argument list on the stack.
+ ///
+ /// The template argument list does not own the template arguments
+ /// provided.
+ explicit TemplateArgumentList(OnStackType,
+ const TemplateArgument *Args, unsigned NumArgs)
+ : Arguments(Args, false), NumArguments(NumArgs) { }
+
+ /// \brief Produces a shallow copy of the given template argument list.
+ ///
+ /// This operation assumes that the input argument list outlives it.
+ /// This takes the list as a pointer to avoid looking like a copy
+ /// constructor, since this really really isn't safe to use that
+ /// way.
+ explicit TemplateArgumentList(const TemplateArgumentList *Other)
+ : Arguments(Other->data(), false), NumArguments(Other->size()) { }
/// \brief Retrieve the template argument at a given index.
const TemplateArgument &get(unsigned Idx) const {
- assert(Idx < NumFlatArguments && "Invalid template argument index");
- return getFlatArgumentList()[Idx];
+ assert(Idx < NumArguments && "Invalid template argument index");
+ return data()[Idx];
}
/// \brief Retrieve the template argument at a given index.
@@ -209,15 +165,11 @@
/// \brief Retrieve the number of template arguments in this
/// template argument list.
- unsigned size() const { return NumFlatArguments; }
+ unsigned size() const { return NumArguments; }
- /// \brief Retrieve the number of template arguments in the
- /// flattened template argument list.
- unsigned flat_size() const { return NumFlatArguments; }
-
- /// \brief Retrieve the flattened template argument list.
- const TemplateArgument *getFlatArgumentList() const {
- return FlatArguments.getPointer();
+ /// \brief Retrieve a pointer to the template argument list.
+ const TemplateArgument *data() const {
+ return Arguments.getPointer();
}
};
@@ -369,8 +321,8 @@
}
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, TemplateArguments->getFlatArgumentList(),
- TemplateArguments->flat_size(),
+ Profile(ID, TemplateArguments->data(),
+ TemplateArguments->size(),
Function->getASTContext());
}
@@ -1229,7 +1181,7 @@
ExplicitSpecializationInfo *ExplicitInfo;
/// \brief The template arguments used to describe this specialization.
- TemplateArgumentList TemplateArgs;
+ TemplateArgumentList *TemplateArgs;
/// \brief The point where this template was instantiated (if any)
SourceLocation PointOfInstantiation;
@@ -1242,7 +1194,8 @@
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate,
- TemplateArgumentListBuilder &Builder,
+ const TemplateArgument *Args,
+ unsigned NumArgs,
ClassTemplateSpecializationDecl *PrevDecl);
explicit ClassTemplateSpecializationDecl(Kind DK);
@@ -1251,7 +1204,8 @@
static ClassTemplateSpecializationDecl *
Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate,
- TemplateArgumentListBuilder &Builder,
+ const TemplateArgument *Args,
+ unsigned NumArgs,
ClassTemplateSpecializationDecl *PrevDecl);
static ClassTemplateSpecializationDecl *
Create(ASTContext &Context, EmptyShell Empty);
@@ -1277,7 +1231,7 @@
/// \brief Retrieve the template arguments of the class template
/// specialization.
const TemplateArgumentList &getTemplateArgs() const {
- return TemplateArgs;
+ return *TemplateArgs;
}
/// \brief Determine the kind of specialization that this
@@ -1413,8 +1367,7 @@
SourceLocation getInnerLocStart() const { return getTemplateKeywordLoc(); }
void Profile(llvm::FoldingSetNodeID &ID) const {
- Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(),
- getASTContext());
+ Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
}
static void
@@ -1470,15 +1423,16 @@
DeclContext *DC, SourceLocation L,
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
- TemplateArgumentListBuilder &Builder,
+ const TemplateArgument *Args,
+ unsigned NumArgs,
TemplateArgumentLoc *ArgInfos,
unsigned NumArgInfos,
ClassTemplatePartialSpecializationDecl *PrevDecl,
unsigned SequenceNumber)
: ClassTemplateSpecializationDecl(Context,
ClassTemplatePartialSpecialization,
- TK, DC, L, SpecializedTemplate, Builder,
- PrevDecl),
+ TK, DC, L, SpecializedTemplate,
+ Args, NumArgs, PrevDecl),
TemplateParams(Params), ArgsAsWritten(ArgInfos),
NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
InstantiatedFromMember(0, false) { }
@@ -1494,7 +1448,8 @@
Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L,
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
- TemplateArgumentListBuilder &Builder,
+ const TemplateArgument *Args,
+ unsigned NumArgs,
const TemplateArgumentListInfo &ArgInfos,
QualType CanonInjectedType,
ClassTemplatePartialSpecializationDecl *PrevDecl,
Modified: cfe/trunk/include/clang/AST/TemplateBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TemplateBase.h?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TemplateBase.h (original)
+++ cfe/trunk/include/clang/AST/TemplateBase.h Sun Nov 7 17:05:16 2010
@@ -44,7 +44,6 @@
struct {
TemplateArgument *Args;
unsigned NumArgs;
- bool CopyArgs;
} Args;
};
@@ -92,6 +91,8 @@
/// \brief Construct an integral constant template argument.
TemplateArgument(const llvm::APSInt &Value, QualType Type) : Kind(Integral) {
+ // FIXME: Large integral values will get leaked. Do something
+ // similar to what we did with IntegerLiteral.
new (Integer.Value) llvm::APSInt(Value);
Integer.Type = Type.getAsOpaquePtr();
}
@@ -115,46 +116,54 @@
TypeOrValue = reinterpret_cast<uintptr_t>(E);
}
+ /// \brief Construct a template argument that is a template argument pack.
+ ///
+ /// We assume that storage for the template arguments provided
+ /// outlives the TemplateArgument itself.
+ TemplateArgument(TemplateArgument *Args, unsigned NumArgs) : Kind(Pack) {
+ this->Args.Args = Args;
+ this->Args.NumArgs = NumArgs;
+ }
+
/// \brief Copy constructor for a template argument.
TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
+ // FIXME: Large integral values will get leaked. Do something
+ // similar to what we did with IntegerLiteral.
if (Kind == Integral) {
new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
Integer.Type = Other.Integer.Type;
} else if (Kind == Pack) {
Args.NumArgs = Other.Args.NumArgs;
- Args.Args = new TemplateArgument[Args.NumArgs];
- for (unsigned I = 0; I != Args.NumArgs; ++I)
- Args.Args[I] = Other.Args.Args[I];
+ Args.Args = Other.Args.Args;
}
else
TypeOrValue = Other.TypeOrValue;
}
TemplateArgument& operator=(const TemplateArgument& Other) {
- // FIXME: Does not provide the strong guarantee for exception
- // safety.
using llvm::APSInt;
- // FIXME: Handle Packs
- assert(Kind != Pack && "FIXME: Handle packs");
- assert(Other.Kind != Pack && "FIXME: Handle packs");
-
if (Kind == Other.Kind && Kind == Integral) {
// Copy integral values.
*this->getAsIntegral() = *Other.getAsIntegral();
Integer.Type = Other.Integer.Type;
+ return *this;
+ }
+
+ // Destroy the current integral value, if that's what we're holding.
+ if (Kind == Integral)
+ getAsIntegral()->~APSInt();
+
+ Kind = Other.Kind;
+
+ if (Other.Kind == Integral) {
+ new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
+ Integer.Type = Other.Integer.Type;
+ } else if (Other.Kind == Pack) {
+ Args.NumArgs = Other.Args.NumArgs;
+ Args.Args = Other.Args.Args;
} else {
- // Destroy the current integral value, if that's what we're holding.
- if (Kind == Integral)
- getAsIntegral()->~APSInt();
-
- Kind = Other.Kind;
-
- if (Other.Kind == Integral) {
- new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
- Integer.Type = Other.Integer.Type;
- } else
- TypeOrValue = Other.TypeOrValue;
+ TypeOrValue = Other.TypeOrValue;
}
return *this;
@@ -165,8 +174,6 @@
if (Kind == Integral)
getAsIntegral()->~APSInt();
- else if (Kind == Pack && Args.CopyArgs)
- delete[] Args.Args;
}
/// \brief Return the kind of stored template argument.
@@ -260,9 +267,6 @@
/// same.
bool structurallyEquals(const TemplateArgument &Other) const;
- /// \brief Construct a template argument pack.
- void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
-
/// \brief Used to insert TemplateArguments into FoldingSets.
void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context) const;
};
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Nov 7 17:05:16 2010
@@ -1769,6 +1769,8 @@
"'template' keyword outside of a template">;
// C++0x Variadic Templates
+def err_variadic_templates_unsupported : Error<
+ "variadic templates are not yet implemented">;
def err_template_param_pack_default_arg : Error<
"template parameter pack cannot have a default argument">;
def err_template_param_pack_must_be_last_template_parameter : Error<
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Sun Nov 7 17:05:16 2010
@@ -121,7 +121,6 @@
class TargetAttributesSema;
class TemplateArgument;
class TemplateArgumentList;
- class TemplateArgumentListBuilder;
class TemplateArgumentLoc;
class TemplateDecl;
class TemplateParameterList;
@@ -2883,7 +2882,7 @@
bool CheckClassTemplatePartialSpecializationArgs(
TemplateParameterList *TemplateParams,
- const TemplateArgumentListBuilder &TemplateArgs,
+ llvm::SmallVectorImpl<TemplateArgument> &TemplateArgs,
bool &MirrorsPrimaryTemplate);
DeclResult
@@ -2958,7 +2957,7 @@
SourceLocation TemplateLoc,
SourceLocation RAngleLoc,
Decl *Param,
- TemplateArgumentListBuilder &Converted);
+ llvm::SmallVectorImpl<TemplateArgument> &Converted);
/// \brief Specifies the context in which a particular template
/// argument is being checked.
@@ -2981,18 +2980,18 @@
TemplateDecl *Template,
SourceLocation TemplateLoc,
SourceLocation RAngleLoc,
- TemplateArgumentListBuilder &Converted,
+ llvm::SmallVectorImpl<TemplateArgument> &Converted,
CheckTemplateArgumentKind CTAK = CTAK_Specified);
bool CheckTemplateArgumentList(TemplateDecl *Template,
SourceLocation TemplateLoc,
const TemplateArgumentListInfo &TemplateArgs,
bool PartialTemplateArgs,
- TemplateArgumentListBuilder &Converted);
+ llvm::SmallVectorImpl<TemplateArgument> &Converted);
bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
const TemplateArgumentLoc &Arg,
- TemplateArgumentListBuilder &Converted);
+ llvm::SmallVectorImpl<TemplateArgument> &Converted);
bool CheckTemplateArgument(TemplateTypeParmDecl *Param,
TypeSourceInfo *Arg);
Modified: cfe/trunk/include/clang/Sema/Template.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Template.h?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Template.h (original)
+++ cfe/trunk/include/clang/Sema/Template.h Sun Nov 7 17:05:16 2010
@@ -82,9 +82,8 @@
/// \brief Add a new outermost level to the multi-level template argument
/// list.
void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) {
- TemplateArgumentLists.push_back(
- ArgList(TemplateArgs->getFlatArgumentList(),
- TemplateArgs->flat_size()));
+ TemplateArgumentLists.push_back(ArgList(TemplateArgs->data(),
+ TemplateArgs->size()));
}
/// \brief Add a new outmost level to the multi-level template argument
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sun Nov 7 17:05:16 2010
@@ -2684,17 +2684,15 @@
return TemplateArgument(getCanonicalType(Arg.getAsType()));
case TemplateArgument::Pack: {
- // FIXME: Allocate in ASTContext
- TemplateArgument *CanonArgs = new TemplateArgument[Arg.pack_size()];
+ TemplateArgument *CanonArgs
+ = new (*this) TemplateArgument[Arg.pack_size()];
unsigned Idx = 0;
for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
AEnd = Arg.pack_end();
A != AEnd; (void)++A, ++Idx)
CanonArgs[Idx] = getCanonicalTemplateArgument(*A);
- TemplateArgument Result;
- Result.setArgumentPack(CanonArgs, Arg.pack_size(), false);
- return Result;
+ return TemplateArgument(CanonArgs, Arg.pack_size());
}
}
@@ -3897,8 +3895,8 @@
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
std::string TemplateArgsStr
= TemplateSpecializationType::PrintTemplateArgumentList(
- TemplateArgs.getFlatArgumentList(),
- TemplateArgs.flat_size(),
+ TemplateArgs.data(),
+ TemplateArgs.size(),
(*this).PrintingPolicy);
S += TemplateArgsStr;
Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Sun Nov 7 17:05:16 2010
@@ -164,8 +164,7 @@
static LVPair
getLVForTemplateArgumentList(const TemplateArgumentList &TArgs) {
- return getLVForTemplateArgumentList(TArgs.getFlatArgumentList(),
- TArgs.flat_size());
+ return getLVForTemplateArgumentList(TArgs.data(), TArgs.size());
}
/// getLVForDecl - Get the cached linkage and visibility for the given
@@ -650,8 +649,8 @@
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
std::string TemplateArgsStr
= TemplateSpecializationType::PrintTemplateArgumentList(
- TemplateArgs.getFlatArgumentList(),
- TemplateArgs.flat_size(),
+ TemplateArgs.data(),
+ TemplateArgs.size(),
P);
OS << Spec->getName() << TemplateArgsStr;
} else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(*I)) {
@@ -1161,8 +1160,8 @@
const TemplateArgumentList *TemplateArgs = getTemplateSpecializationArgs();
if (TemplateArgs)
S += TemplateSpecializationType::PrintTemplateArgumentList(
- TemplateArgs->getFlatArgumentList(),
- TemplateArgs->flat_size(),
+ TemplateArgs->data(),
+ TemplateArgs->size(),
Policy);
}
Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Sun Nov 7 17:05:16 2010
@@ -19,6 +19,7 @@
#include "clang/AST/ASTMutationListener.h"
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/STLExtras.h"
+#include <memory>
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -394,120 +395,20 @@
}
//===----------------------------------------------------------------------===//
-// TemplateArgumentListBuilder Implementation
-//===----------------------------------------------------------------------===//
-
-void TemplateArgumentListBuilder::Append(const TemplateArgument &Arg) {
- assert((Arg.getKind() != TemplateArgument::Type ||
- Arg.getAsType().isCanonical()) && "Type must be canonical!");
- assert(FlatArgs.size() < MaxFlatArgs && "Argument list builder is full!");
- assert(!StructuredArgs &&
- "Can't append arguments when an argument pack has been added!");
-
- FlatArgs.push_back(Arg);
-}
-
-void TemplateArgumentListBuilder::BeginPack() {
- assert(!AddingToPack && "Already adding to pack!");
- assert(!StructuredArgs && "Argument list already contains a pack!");
-
- AddingToPack = true;
- PackBeginIndex = FlatArgs.size();
-}
-
-void TemplateArgumentListBuilder::EndPack() {
- assert(AddingToPack && "Not adding to pack!");
- assert(!StructuredArgs && "Argument list already contains a pack!");
-
- AddingToPack = false;
-
- // FIXME: This is a memory leak!
- StructuredArgs = new TemplateArgument[MaxStructuredArgs];
-
- // First copy the flat entries over to the list (if any)
- for (unsigned I = 0; I != PackBeginIndex; ++I) {
- NumStructuredArgs++;
- StructuredArgs[I] = FlatArgs[I];
- }
-
- // Next, set the pack.
- TemplateArgument *PackArgs = 0;
- unsigned NumPackArgs = NumFlatArgs - PackBeginIndex;
- // FIXME: NumPackArgs shouldn't be negative here???
- if (NumPackArgs)
- PackArgs = FlatArgs.data()+PackBeginIndex;
-
- StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs,
- /*CopyArgs=*/false);
-}
-
-//===----------------------------------------------------------------------===//
// TemplateArgumentList Implementation
//===----------------------------------------------------------------------===//
-TemplateArgumentList::TemplateArgumentList(ASTContext &Context,
- TemplateArgumentListBuilder &Builder,
- bool TakeArgs)
- : FlatArguments(Builder.getFlatArguments(), TakeArgs),
- NumFlatArguments(Builder.flatSize()),
- StructuredArguments(Builder.getStructuredArguments(), TakeArgs),
- NumStructuredArguments(Builder.structuredSize()) {
-
- if (!TakeArgs)
- return;
-
- // If this does take ownership of the arguments, then we have to new them
- // and copy over.
- TemplateArgument *NewArgs =
- new (Context) TemplateArgument[Builder.flatSize()];
- std::copy(Builder.getFlatArguments(),
- Builder.getFlatArguments()+Builder.flatSize(), NewArgs);
- FlatArguments.setPointer(NewArgs);
-
- // Just reuse the structured and flat arguments array if possible.
- if (Builder.getStructuredArguments() == Builder.getFlatArguments()) {
- StructuredArguments.setPointer(NewArgs);
- StructuredArguments.setInt(0);
- } else {
- TemplateArgument *NewSArgs =
- new (Context) TemplateArgument[Builder.flatSize()];
- std::copy(Builder.getFlatArguments(),
- Builder.getFlatArguments()+Builder.flatSize(), NewSArgs);
- StructuredArguments.setPointer(NewSArgs);
- }
-}
-
-TemplateArgumentList::TemplateArgumentList(ASTContext &Context,
- const TemplateArgument *Args,
- unsigned NumArgs)
- : NumFlatArguments(0), NumStructuredArguments(0) {
- init(Context, Args, NumArgs);
-}
-
-/// Produces a shallow copy of the given template argument list. This
-/// assumes that the input argument list outlives it. This takes the list as
-/// a pointer to avoid looking like a copy constructor, since this really
-/// really isn't safe to use that way.
-TemplateArgumentList::TemplateArgumentList(const TemplateArgumentList *Other)
- : FlatArguments(Other->FlatArguments.getPointer(), false),
- NumFlatArguments(Other->flat_size()),
- StructuredArguments(Other->StructuredArguments.getPointer(), false),
- NumStructuredArguments(Other->NumStructuredArguments) { }
-
-void TemplateArgumentList::init(ASTContext &Context,
- const TemplateArgument *Args,
- unsigned NumArgs) {
-assert(NumFlatArguments == 0 && NumStructuredArguments == 0 &&
- "Already initialized!");
-
-NumFlatArguments = NumStructuredArguments = NumArgs;
-TemplateArgument *NewArgs = new (Context) TemplateArgument[NumArgs];
-std::copy(Args, Args+NumArgs, NewArgs);
-FlatArguments.setPointer(NewArgs);
-FlatArguments.setInt(1); // Owns the pointer.
-
-// Just reuse the flat arguments array.
-StructuredArguments.setPointer(NewArgs);
-StructuredArguments.setInt(0); // Doesn't own the pointer.
+TemplateArgumentList *
+TemplateArgumentList::CreateCopy(ASTContext &Context,
+ const TemplateArgument *Args,
+ unsigned NumArgs) {
+ std::size_t Size = sizeof(TemplateArgumentList)
+ + NumArgs * sizeof(TemplateArgument);
+ void *Mem = Context.Allocate(Size);
+ TemplateArgument *StoredArgs
+ = reinterpret_cast<TemplateArgument *>(
+ static_cast<TemplateArgumentList *>(Mem) + 1);
+ std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
+ return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
}
//===----------------------------------------------------------------------===//
@@ -517,14 +418,15 @@
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate,
- TemplateArgumentListBuilder &Builder,
+ const TemplateArgument *Args,
+ unsigned NumArgs,
ClassTemplateSpecializationDecl *PrevDecl)
: CXXRecordDecl(DK, TK, DC, L,
SpecializedTemplate->getIdentifier(),
PrevDecl),
SpecializedTemplate(SpecializedTemplate),
ExplicitInfo(0),
- TemplateArgs(Context, Builder, /*TakeArgs=*/true),
+ TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
SpecializationKind(TSK_Undeclared) {
}
@@ -538,14 +440,15 @@
ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate,
- TemplateArgumentListBuilder &Builder,
+ const TemplateArgument *Args,
+ unsigned NumArgs,
ClassTemplateSpecializationDecl *PrevDecl) {
ClassTemplateSpecializationDecl *Result
= new (Context)ClassTemplateSpecializationDecl(Context,
ClassTemplateSpecialization,
TK, DC, L,
SpecializedTemplate,
- Builder,
+ Args, NumArgs,
PrevDecl);
Context.getTypeDeclType(Result, PrevDecl);
return Result;
@@ -565,8 +468,8 @@
const TemplateArgumentList &TemplateArgs = getTemplateArgs();
S += TemplateSpecializationType::PrintTemplateArgumentList(
- TemplateArgs.getFlatArgumentList(),
- TemplateArgs.flat_size(),
+ TemplateArgs.data(),
+ TemplateArgs.size(),
Policy);
}
@@ -586,7 +489,8 @@
Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L,
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
- TemplateArgumentListBuilder &Builder,
+ const TemplateArgument *Args,
+ unsigned NumArgs,
const TemplateArgumentListInfo &ArgInfos,
QualType CanonInjectedType,
ClassTemplatePartialSpecializationDecl *PrevDecl,
@@ -600,7 +504,7 @@
= new (Context)ClassTemplatePartialSpecializationDecl(Context, TK,
DC, L, Params,
SpecializedTemplate,
- Builder,
+ Args, NumArgs,
ClonedArgs, N,
PrevDecl,
SequenceNumber);
Modified: cfe/trunk/lib/AST/TemplateBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateBase.cpp?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TemplateBase.cpp (original)
+++ cfe/trunk/lib/AST/TemplateBase.cpp Sun Nov 7 17:05:16 2010
@@ -26,25 +26,6 @@
// TemplateArgument Implementation
//===----------------------------------------------------------------------===//
-/// \brief Construct a template argument pack.
-void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs,
- bool CopyArgs) {
- assert(isNull() && "Must call setArgumentPack on a null argument");
-
- Kind = Pack;
- Args.NumArgs = NumArgs;
- Args.CopyArgs = CopyArgs;
- if (!Args.CopyArgs) {
- Args.Args = args;
- return;
- }
-
- // FIXME: Allocate in ASTContext
- Args.Args = new TemplateArgument[NumArgs];
- for (unsigned I = 0; I != Args.NumArgs; ++I)
- Args.Args[I] = args[I];
-}
-
void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
ASTContext &Context) const {
ID.AddInteger(Kind);
Modified: cfe/trunk/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Sun Nov 7 17:05:16 2010
@@ -426,8 +426,8 @@
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
std::string TemplateArgsStr
= TemplateSpecializationType::PrintTemplateArgumentList(
- TemplateArgs.getFlatArgumentList(),
- TemplateArgs.flat_size(),
+ TemplateArgs.data(),
+ TemplateArgs.size(),
Policy);
Buffer += Spec->getIdentifier()->getName();
Buffer += TemplateArgsStr;
@@ -506,8 +506,8 @@
NumArgs = TST->getNumArgs();
} else {
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
- Args = TemplateArgs.getFlatArgumentList();
- NumArgs = TemplateArgs.flat_size();
+ Args = TemplateArgs.data();
+ NumArgs = TemplateArgs.size();
}
Buffer += TemplateSpecializationType::PrintTemplateArgumentList(Args,
NumArgs,
Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Sun Nov 7 17:05:16 2010
@@ -136,8 +136,8 @@
NumArgs = TST->getNumArgs();
} else {
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
- Args = TemplateArgs.getFlatArgumentList();
- NumArgs = TemplateArgs.flat_size();
+ Args = TemplateArgs.data();
+ NumArgs = TemplateArgs.size();
}
Buffer = RD->getIdentifier()->getNameStart();
PrintingPolicy Policy(CGM.getLangOptions());
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sun Nov 7 17:05:16 2010
@@ -8039,8 +8039,7 @@
if (ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl())) {
const TemplateArgumentList &Args = Spec->getTemplateArgs();
- return TraverseTemplateArguments(Args.getFlatArgumentList(),
- Args.flat_size());
+ return TraverseTemplateArguments(Args.data(), Args.size());
}
return true;
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Sun Nov 7 17:05:16 2010
@@ -1507,14 +1507,12 @@
// Check that the template argument list is well-formed for this
// template.
- TemplateArgumentListBuilder Converted(Template->getTemplateParameters(),
- TemplateArgs.size());
+ llvm::SmallVector<TemplateArgument, 4> Converted;
if (CheckTemplateArgumentList(Template, TemplateLoc, TemplateArgs,
false, Converted))
return QualType();
- assert((Converted.structuredSize() ==
- Template->getTemplateParameters()->size()) &&
+ assert((Converted.size() == Template->getTemplateParameters()->size()) &&
"Converted template argument list is too short!");
QualType CanonType;
@@ -1531,8 +1529,8 @@
// template<typename T, typename U = T> struct A;
TemplateName CanonName = Context.getCanonicalTemplateName(Name);
CanonType = Context.getTemplateSpecializationType(CanonName,
- Converted.getFlatArguments(),
- Converted.flatSize());
+ Converted.data(),
+ Converted.size());
// FIXME: CanonType is not actually the canonical type, and unfortunately
// it is a TemplateSpecializationType that we will never use again.
@@ -1583,8 +1581,8 @@
// corresponds to these arguments.
void *InsertPos = 0;
ClassTemplateSpecializationDecl *Decl
- = ClassTemplate->findSpecialization(Converted.getFlatArguments(),
- Converted.flatSize(), InsertPos);
+ = ClassTemplate->findSpecialization(Converted.data(), Converted.size(),
+ InsertPos);
if (!Decl) {
// This is the first time we have referenced this class template
// specialization. Create the canonical declaration and add it to
@@ -1593,8 +1591,9 @@
ClassTemplate->getTemplatedDecl()->getTagKind(),
ClassTemplate->getDeclContext(),
ClassTemplate->getLocation(),
- ClassTemplate,
- Converted, 0);
+ ClassTemplate,
+ Converted.data(),
+ Converted.size(), 0);
ClassTemplate->AddSpecialization(Decl, InsertPos);
Decl->setLexicalDeclContext(CurContext);
}
@@ -1839,7 +1838,7 @@
bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
const TemplateArgumentLoc &AL,
- TemplateArgumentListBuilder &Converted) {
+ llvm::SmallVectorImpl<TemplateArgument> &Converted) {
const TemplateArgument &Arg = AL.getArgument();
// Check template type parameter.
@@ -1876,7 +1875,7 @@
return true;
// Add the converted template type argument.
- Converted.Append(
+ Converted.push_back(
TemplateArgument(Context.getCanonicalType(Arg.getAsType())));
return false;
}
@@ -1909,21 +1908,21 @@
SourceLocation TemplateLoc,
SourceLocation RAngleLoc,
TemplateTypeParmDecl *Param,
- TemplateArgumentListBuilder &Converted) {
+ llvm::SmallVectorImpl<TemplateArgument> &Converted) {
TypeSourceInfo *ArgType = Param->getDefaultArgumentInfo();
// If the argument type is dependent, instantiate it now based
// on the previously-computed template arguments.
if (ArgType->getType()->isDependentType()) {
- TemplateArgumentList TemplateArgs(SemaRef.Context, Converted,
- /*TakeArgs=*/false);
+ TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
+ Converted.data(), Converted.size());
MultiLevelTemplateArgumentList AllTemplateArgs
= SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs);
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
- Template, Converted.getFlatArguments(),
- Converted.flatSize(),
+ Template, Converted.data(),
+ Converted.size(),
SourceRange(TemplateLoc, RAngleLoc));
ArgType = SemaRef.SubstType(ArgType, AllTemplateArgs,
@@ -1962,16 +1961,16 @@
SourceLocation TemplateLoc,
SourceLocation RAngleLoc,
NonTypeTemplateParmDecl *Param,
- TemplateArgumentListBuilder &Converted) {
- TemplateArgumentList TemplateArgs(SemaRef.Context, Converted,
- /*TakeArgs=*/false);
+ llvm::SmallVectorImpl<TemplateArgument> &Converted) {
+ TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
+ Converted.data(), Converted.size());
MultiLevelTemplateArgumentList AllTemplateArgs
= SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs);
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
- Template, Converted.getFlatArguments(),
- Converted.flatSize(),
+ Template, Converted.data(),
+ Converted.size(),
SourceRange(TemplateLoc, RAngleLoc));
return SemaRef.SubstExpr(Param->getDefaultArgument(), AllTemplateArgs);
@@ -2005,16 +2004,16 @@
SourceLocation TemplateLoc,
SourceLocation RAngleLoc,
TemplateTemplateParmDecl *Param,
- TemplateArgumentListBuilder &Converted) {
- TemplateArgumentList TemplateArgs(SemaRef.Context, Converted,
- /*TakeArgs=*/false);
+ llvm::SmallVectorImpl<TemplateArgument> &Converted) {
+ TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
+ Converted.data(), Converted.size());
MultiLevelTemplateArgumentList AllTemplateArgs
= SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs);
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
- Template, Converted.getFlatArguments(),
- Converted.flatSize(),
+ Template, Converted.data(),
+ Converted.size(),
SourceRange(TemplateLoc, RAngleLoc));
return SemaRef.SubstTemplateName(
@@ -2031,8 +2030,8 @@
SourceLocation TemplateLoc,
SourceLocation RAngleLoc,
Decl *Param,
- TemplateArgumentListBuilder &Converted) {
- if (TemplateTypeParmDecl *TypeParm = dyn_cast<TemplateTypeParmDecl>(Param)) {
+ llvm::SmallVectorImpl<TemplateArgument> &Converted) {
+ if (TemplateTypeParmDecl *TypeParm = dyn_cast<TemplateTypeParmDecl>(Param)) {
if (!TypeParm->hasDefaultArgument())
return TemplateArgumentLoc();
@@ -2089,7 +2088,7 @@
TemplateDecl *Template,
SourceLocation TemplateLoc,
SourceLocation RAngleLoc,
- TemplateArgumentListBuilder &Converted,
+ llvm::SmallVectorImpl<TemplateArgument> &Converted,
CheckTemplateArgumentKind CTAK) {
// Check template type parameters.
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
@@ -2103,12 +2102,11 @@
if (NTTPType->isDependentType()) {
// Do substitution on the type of the non-type template parameter.
InstantiatingTemplate Inst(*this, TemplateLoc, Template,
- NTTP, Converted.getFlatArguments(),
- Converted.flatSize(),
+ NTTP, Converted.data(), Converted.size(),
SourceRange(TemplateLoc, RAngleLoc));
- TemplateArgumentList TemplateArgs(Context, Converted,
- /*TakeArgs=*/false);
+ TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
+ Converted.data(), Converted.size());
NTTPType = SubstType(NTTPType,
MultiLevelTemplateArgumentList(TemplateArgs),
NTTP->getLocation(),
@@ -2133,7 +2131,7 @@
if (CheckTemplateArgument(NTTP, NTTPType, E, Result, CTAK))
return true;
- Converted.Append(Result);
+ Converted.push_back(Result);
break;
}
@@ -2141,7 +2139,7 @@
case TemplateArgument::Integral:
// We've already checked this template argument, so just copy
// it to the list of converted arguments.
- Converted.Append(Arg.getArgument());
+ Converted.push_back(Arg.getArgument());
break;
case TemplateArgument::Template:
@@ -2166,7 +2164,7 @@
if (CheckTemplateArgument(NTTP, NTTPType, E, Result))
return true;
- Converted.Append(Result);
+ Converted.push_back(Result);
break;
}
@@ -2219,12 +2217,11 @@
// Set up a template instantiation context.
LocalInstantiationScope Scope(*this);
InstantiatingTemplate Inst(*this, TemplateLoc, Template,
- TempParm, Converted.getFlatArguments(),
- Converted.flatSize(),
+ TempParm, Converted.data(), Converted.size(),
SourceRange(TemplateLoc, RAngleLoc));
- TemplateArgumentList TemplateArgs(Context, Converted,
- /*TakeArgs=*/false);
+ TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
+ Converted.data(), Converted.size());
TempParm = cast_or_null<TemplateTemplateParmDecl>(
SubstDecl(TempParm, CurContext,
MultiLevelTemplateArgumentList(TemplateArgs)));
@@ -2243,7 +2240,7 @@
if (CheckTemplateArgument(TempParm, Arg))
return true;
- Converted.Append(Arg.getArgument());
+ Converted.push_back(Arg.getArgument());
break;
case TemplateArgument::Expression:
@@ -2276,7 +2273,7 @@
SourceLocation TemplateLoc,
const TemplateArgumentListInfo &TemplateArgs,
bool PartialTemplateArgs,
- TemplateArgumentListBuilder &Converted) {
+ llvm::SmallVectorImpl<TemplateArgument> &Converted) {
TemplateParameterList *Params = Template->getTemplateParameters();
unsigned NumParams = Params->size();
unsigned NumArgs = TemplateArgs.size();
@@ -2322,16 +2319,8 @@
// If we have a template parameter pack, check every remaining template
// argument against that template parameter pack.
if ((*Param)->isTemplateParameterPack()) {
- Converted.BeginPack();
- for (; ArgIdx < NumArgs; ++ArgIdx) {
- if (CheckTemplateArgument(*Param, TemplateArgs[ArgIdx], Template,
- TemplateLoc, RAngleLoc, Converted)) {
- Invalid = true;
- break;
- }
- }
- Converted.EndPack();
- continue;
+ Diag(TemplateLoc, diag::err_variadic_templates_unsupported);
+ return true;
}
if (ArgIdx < NumArgs) {
@@ -2410,8 +2399,7 @@
// Introduce an instantiation record that describes where we are using
// the default template argument.
InstantiatingTemplate Instantiating(*this, RAngleLoc, Template, *Param,
- Converted.getFlatArguments(),
- Converted.flatSize(),
+ Converted.data(), Converted.size(),
SourceRange(TemplateLoc, RAngleLoc));
// Check the default template argument.
@@ -3805,13 +3793,13 @@
/// \returns true if there was an error, false otherwise.
bool Sema::CheckClassTemplatePartialSpecializationArgs(
TemplateParameterList *TemplateParams,
- const TemplateArgumentListBuilder &TemplateArgs,
+ llvm::SmallVectorImpl<TemplateArgument> &TemplateArgs,
bool &MirrorsPrimaryTemplate) {
// FIXME: the interface to this function will have to change to
// accommodate variadic templates.
MirrorsPrimaryTemplate = true;
- const TemplateArgument *ArgList = TemplateArgs.getFlatArguments();
+ const TemplateArgument *ArgList = TemplateArgs.data();
for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
// Determine whether the template argument list of the partial
@@ -4036,14 +4024,12 @@
// Check that the template argument list is well-formed for this
// template.
- TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(),
- TemplateArgs.size());
+ llvm::SmallVector<TemplateArgument, 4> Converted;
if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc,
TemplateArgs, false, Converted))
return true;
- assert((Converted.structuredSize() ==
- ClassTemplate->getTemplateParameters()->size()) &&
+ assert((Converted.size() == ClassTemplate->getTemplateParameters()->size()) &&
"Converted template argument list is too short!");
// Find the class template (partial) specialization declaration that
@@ -4089,13 +4075,13 @@
if (isPartialSpecialization)
// FIXME: Template parameter list matters, too
PrevDecl
- = ClassTemplate->findPartialSpecialization(Converted.getFlatArguments(),
- Converted.flatSize(),
+ = ClassTemplate->findPartialSpecialization(Converted.data(),
+ Converted.size(),
InsertPos);
else
PrevDecl
- = ClassTemplate->findSpecialization(Converted.getFlatArguments(),
- Converted.flatSize(), InsertPos);
+ = ClassTemplate->findSpecialization(Converted.data(),
+ Converted.size(), InsertPos);
ClassTemplateSpecializationDecl *Specialization = 0;
@@ -4126,8 +4112,8 @@
// arguments of the class template partial specialization.
TemplateName CanonTemplate = Context.getCanonicalTemplateName(Name);
CanonType = Context.getTemplateSpecializationType(CanonTemplate,
- Converted.getFlatArguments(),
- Converted.flatSize());
+ Converted.data(),
+ Converted.size());
// Create a new class template partial specialization declaration node.
ClassTemplatePartialSpecializationDecl *PrevPartial
@@ -4140,7 +4126,8 @@
TemplateNameLoc,
TemplateParams,
ClassTemplate,
- Converted,
+ Converted.data(),
+ Converted.size(),
TemplateArgs,
CanonType,
PrevPartial,
@@ -4201,7 +4188,8 @@
ClassTemplate->getDeclContext(),
TemplateNameLoc,
ClassTemplate,
- Converted,
+ Converted.data(),
+ Converted.size(),
PrevDecl);
SetNestedNameSpecifier(Specialization, SS);
if (NumMatchedTemplateParamLists > 0 && SS.isSet()) {
@@ -4995,22 +4983,20 @@
// Check that the template argument list is well-formed for this
// template.
- TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(),
- TemplateArgs.size());
+ llvm::SmallVector<TemplateArgument, 4> Converted;
if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc,
TemplateArgs, false, Converted))
return true;
- assert((Converted.structuredSize() ==
- ClassTemplate->getTemplateParameters()->size()) &&
+ assert((Converted.size() == ClassTemplate->getTemplateParameters()->size()) &&
"Converted template argument list is too short!");
// Find the class template specialization declaration that
// corresponds to these arguments.
void *InsertPos = 0;
ClassTemplateSpecializationDecl *PrevDecl
- = ClassTemplate->findSpecialization(Converted.getFlatArguments(),
- Converted.flatSize(), InsertPos);
+ = ClassTemplate->findSpecialization(Converted.data(),
+ Converted.size(), InsertPos);
TemplateSpecializationKind PrevDecl_TSK
= PrevDecl ? PrevDecl->getTemplateSpecializationKind() : TSK_Undeclared;
@@ -5060,7 +5046,9 @@
ClassTemplate->getDeclContext(),
TemplateNameLoc,
ClassTemplate,
- Converted, PrevDecl);
+ Converted.data(),
+ Converted.size(),
+ PrevDecl);
SetNestedNameSpecifier(Specialization, SS);
if (!HasNoEffect && !PrevDecl) {
@@ -5824,9 +5812,7 @@
std::string
Sema::getTemplateArgumentBindingsText(const TemplateParameterList *Params,
const TemplateArgumentList &Args) {
- // FIXME: For variadic templates, we'll need to get the structured list.
- return getTemplateArgumentBindingsText(Params, Args.getFlatArgumentList(),
- Args.flat_size());
+ return getTemplateArgumentBindingsText(Params, Args.data(), Args.size());
}
std::string
Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Sun Nov 7 17:05:16 2010
@@ -1020,8 +1020,7 @@
// C++ [temp.deduct.type]p2:
// [...] or if any template argument remains neither deduced nor
// explicitly specified, template argument deduction fails.
- TemplateArgumentListBuilder Builder(Partial->getTemplateParameters(),
- Deduced.size());
+ llvm::SmallVector<TemplateArgument, 4> Builder;
for (unsigned I = 0, N = Deduced.size(); I != N; ++I) {
if (Deduced[I].isNull()) {
Decl *Param
@@ -1031,13 +1030,14 @@
return Sema::TDK_Incomplete;
}
- Builder.Append(Deduced[I]);
+ Builder.push_back(Deduced[I]);
}
// Form the template argument list from the deduced template arguments.
TemplateArgumentList *DeducedArgumentList
- = new (S.Context) TemplateArgumentList(S.Context, Builder,
- /*TakeArgs=*/true);
+ = TemplateArgumentList::CreateCopy(S.Context, Builder.data(),
+ Builder.size());
+
Info.reset(DeducedArgumentList);
// Substitute the deduced template arguments into the template
@@ -1069,15 +1069,13 @@
InstArgs.addArgument(InstArg);
}
- TemplateArgumentListBuilder ConvertedInstArgs(
- ClassTemplate->getTemplateParameters(), N);
-
+ llvm::SmallVector<TemplateArgument, 4> ConvertedInstArgs;
if (S.CheckTemplateArgumentList(ClassTemplate, Partial->getLocation(),
InstArgs, false, ConvertedInstArgs))
return Sema::TDK_SubstitutionFailure;
- for (unsigned I = 0, E = ConvertedInstArgs.flatSize(); I != E; ++I) {
- TemplateArgument InstArg = ConvertedInstArgs.getFlatArguments()[I];
+ for (unsigned I = 0, E = ConvertedInstArgs.size(); I != E; ++I) {
+ TemplateArgument InstArg = ConvertedInstArgs.data()[I];
Decl *Param = const_cast<NamedDecl *>(
ClassTemplate->getTemplateParameters()->getParam(I));
@@ -1213,8 +1211,7 @@
// declaration order of their corresponding template-parameters. The
// template argument list shall not specify more template-arguments than
// there are corresponding template-parameters.
- TemplateArgumentListBuilder Builder(TemplateParams,
- ExplicitTemplateArgs.size());
+ llvm::SmallVector<TemplateArgument, 4> Builder;
// Enter a new template instantiation context where we check the
// explicitly-specified template arguments against this function template,
@@ -1231,7 +1228,7 @@
ExplicitTemplateArgs,
true,
Builder) || Trap.hasErrorOccurred()) {
- unsigned Index = Builder.structuredSize();
+ unsigned Index = Builder.size();
if (Index >= TemplateParams->size())
Index = TemplateParams->size() - 1;
Info.Param = makeTemplateParameter(TemplateParams->getParam(Index));
@@ -1241,7 +1238,7 @@
// Form the template argument list from the explicitly-specified
// template arguments.
TemplateArgumentList *ExplicitArgumentList
- = new (Context) TemplateArgumentList(Context, Builder, /*TakeArgs=*/true);
+ = TemplateArgumentList::CreateCopy(Context, Builder.data(), Builder.size());
Info.reset(ExplicitArgumentList);
// Template argument deduction and the final substitution should be
@@ -1392,7 +1389,7 @@
// C++ [temp.deduct.type]p2:
// [...] or if any template argument remains neither deduced nor
// explicitly specified, template argument deduction fails.
- TemplateArgumentListBuilder Builder(TemplateParams, Deduced.size());
+ llvm::SmallVector<TemplateArgument, 4> Builder;
for (unsigned I = 0, N = Deduced.size(); I != N; ++I) {
NamedDecl *Param = FunctionTemplate->getTemplateParameters()->getParam(I);
if (!Deduced[I].isNull()) {
@@ -1400,7 +1397,7 @@
// We have already fully type-checked and converted this
// argument, because it was explicitly-specified. Just record the
// presence of this argument.
- Builder.Append(Deduced[I]);
+ Builder.push_back(Deduced[I]);
continue;
}
@@ -1416,16 +1413,18 @@
if (Deduced[I].getKind() == TemplateArgument::Declaration) {
NTTPType = NTTP->getType();
if (NTTPType->isDependentType()) {
- TemplateArgumentList TemplateArgs(Context, Builder,
- /*TakeArgs=*/false);
+ TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
+ Builder.data(), Builder.size());
NTTPType = SubstType(NTTPType,
MultiLevelTemplateArgumentList(TemplateArgs),
NTTP->getLocation(),
NTTP->getDeclName());
if (NTTPType.isNull()) {
Info.Param = makeTemplateParameter(Param);
- Info.reset(new (Context) TemplateArgumentList(Context, Builder,
- /*TakeArgs=*/true));
+ // FIXME: These template arguments are temporary. Free them!
+ Info.reset(TemplateArgumentList::CreateCopy(Context,
+ Builder.data(),
+ Builder.size()));
return TDK_SubstitutionFailure;
}
}
@@ -1451,8 +1450,9 @@
: CTAK_Deduced)) {
Info.Param = makeTemplateParameter(
const_cast<NamedDecl *>(TemplateParams->getParam(I)));
- Info.reset(new (Context) TemplateArgumentList(Context, Builder,
- /*TakeArgs=*/true));
+ // FIXME: These template arguments are temporary. Free them!
+ Info.reset(TemplateArgumentList::CreateCopy(Context, Builder.data(),
+ Builder.size()));
return TDK_SubstitutionFailure;
}
@@ -1483,8 +1483,9 @@
CTAK_Deduced)) {
Info.Param = makeTemplateParameter(
const_cast<NamedDecl *>(TemplateParams->getParam(I)));
- Info.reset(new (Context) TemplateArgumentList(Context, Builder,
- /*TakeArgs=*/true));
+ // FIXME: These template arguments are temporary. Free them!
+ Info.reset(TemplateArgumentList::CreateCopy(Context, Builder.data(),
+ Builder.size()));
return TDK_SubstitutionFailure;
}
@@ -1493,7 +1494,7 @@
// Form the template argument list from the deduced template arguments.
TemplateArgumentList *DeducedArgumentList
- = new (Context) TemplateArgumentList(Context, Builder, /*TakeArgs=*/true);
+ = TemplateArgumentList::CreateCopy(Context, Builder.data(), Builder.size());
Info.reset(DeducedArgumentList);
// Substitute the deduced template arguments into the function template
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Sun Nov 7 17:05:16 2010
@@ -1102,7 +1102,7 @@
std::pair<const TemplateArgument *, unsigned> Innermost
= TemplateArgs.getInnermost();
Function->setFunctionTemplateSpecialization(FunctionTemplate,
- new (SemaRef.Context) TemplateArgumentList(SemaRef.Context,
+ TemplateArgumentList::CreateCopy(SemaRef.Context,
Innermost.first,
Innermost.second),
InsertPos);
@@ -1410,9 +1410,9 @@
std::pair<const TemplateArgument *, unsigned> Innermost
= TemplateArgs.getInnermost();
Method->setFunctionTemplateSpecialization(FunctionTemplate,
- new (SemaRef.Context) TemplateArgumentList(SemaRef.Context,
- Innermost.first,
- Innermost.second),
+ TemplateArgumentList::CreateCopy(SemaRef.Context,
+ Innermost.first,
+ Innermost.second),
InsertPos);
} else if (!isFriend) {
// Record that this is an instantiation of a member function.
@@ -1842,8 +1842,7 @@
// Check that the template argument list is well-formed for this
// class template.
- TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(),
- InstTemplateArgs.size());
+ llvm::SmallVector<TemplateArgument, 4> Converted;
if (SemaRef.CheckTemplateArgumentList(ClassTemplate,
PartialSpec->getLocation(),
InstTemplateArgs,
@@ -1855,15 +1854,15 @@
// in the member template's set of class template partial specializations.
void *InsertPos = 0;
ClassTemplateSpecializationDecl *PrevDecl
- = ClassTemplate->findPartialSpecialization(Converted.getFlatArguments(),
- Converted.flatSize(), InsertPos);
+ = ClassTemplate->findPartialSpecialization(Converted.data(),
+ Converted.size(), InsertPos);
// Build the canonical type that describes the converted template
// arguments of the class template partial specialization.
QualType CanonType
= SemaRef.Context.getTemplateSpecializationType(TemplateName(ClassTemplate),
- Converted.getFlatArguments(),
- Converted.flatSize());
+ Converted.data(),
+ Converted.size());
// Build the fully-sugared type for this class template
// specialization as the user wrote in the specialization
@@ -1911,7 +1910,8 @@
PartialSpec->getLocation(),
InstParams,
ClassTemplate,
- Converted,
+ Converted.data(),
+ Converted.size(),
InstTemplateArgs,
CanonType,
0,
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Sun Nov 7 17:05:16 2010
@@ -2359,10 +2359,14 @@
TransformedArgs.push_back(OutputArg.getArgument());
}
- TemplateArgument Result;
- Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
- true);
- Output = TemplateArgumentLoc(Result, Input.getLocInfo());
+
+ TemplateArgument *TransformedArgsPtr
+ = new (getSema().Context) TemplateArgument[TransformedArgs.size()];
+ std::copy(TransformedArgs.begin(), TransformedArgs.end(),
+ TransformedArgsPtr);
+ Output = TemplateArgumentLoc(TemplateArgument(TransformedArgsPtr,
+ TransformedArgs.size()),
+ Input.getLocInfo());
return false;
}
}
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Sun Nov 7 17:05:16 2010
@@ -4168,13 +4168,10 @@
return TemplateArgument(ReadExpr(F));
case TemplateArgument::Pack: {
unsigned NumArgs = Record[Idx++];
- llvm::SmallVector<TemplateArgument, 8> Args;
- Args.reserve(NumArgs);
- while (NumArgs--)
- Args.push_back(ReadTemplateArgument(F, Record, Idx));
- TemplateArgument TemplArg;
- TemplArg.setArgumentPack(Args.data(), Args.size(), /*CopyArgs=*/true);
- return TemplArg;
+ TemplateArgument *Args = new (*Context) TemplateArgument[NumArgs];
+ for (unsigned I = 0; I != NumArgs; ++I)
+ Args[I] = ReadTemplateArgument(F, Record, Idx);
+ return TemplateArgument(Args, NumArgs);
}
}
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Sun Nov 7 17:05:16 2010
@@ -327,7 +327,7 @@
ASTContext &C = *Reader.getContext();
TemplateArgumentList *TemplArgList
- = new (C) TemplateArgumentList(C, TemplArgs.data(), TemplArgs.size());
+ = TemplateArgumentList::CreateCopy(C, TemplArgs.data(), TemplArgs.size());
TemplateArgumentListInfo *TemplArgsInfo
= new (C) TemplateArgumentListInfo(LAngleLoc, RAngleLoc);
for (unsigned i=0, e = TemplArgLocs.size(); i != e; ++i)
@@ -1051,7 +1051,8 @@
llvm::SmallVector<TemplateArgument, 8> TemplArgs;
Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
TemplateArgumentList *ArgList
- = new (C) TemplateArgumentList(C, TemplArgs.data(), TemplArgs.size());
+ = TemplateArgumentList::CreateCopy(C, TemplArgs.data(),
+ TemplArgs.size());
ClassTemplateSpecializationDecl::SpecializedPartialSpecialization *PS
= new (C) ClassTemplateSpecializationDecl::
SpecializedPartialSpecialization();
@@ -1074,7 +1075,8 @@
llvm::SmallVector<TemplateArgument, 8> TemplArgs;
Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
- D->TemplateArgs.init(C, TemplArgs.data(), TemplArgs.size());
+ D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs.data(),
+ TemplArgs.size());
D->PointOfInstantiation = ReadSourceLocation(Record, Idx);
D->SpecializationKind = (TemplateSpecializationKind)Record[Idx++];
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Sun Nov 7 17:05:16 2010
@@ -3180,8 +3180,8 @@
ASTWriter::AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs,
RecordDataImpl &Record) {
assert(TemplateArgs && "No TemplateArgs!");
- Record.push_back(TemplateArgs->flat_size());
- for (int i=0, e = TemplateArgs->flat_size(); i != e; ++i)
+ Record.push_back(TemplateArgs->size());
+ for (int i=0, e = TemplateArgs->size(); i != e; ++i)
AddTemplateArgument(TemplateArgs->get(i), Record);
}
Removed: cfe/trunk/test/SemaTemplate/variadic-class-template-1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/variadic-class-template-1.cpp?rev=118384&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/variadic-class-template-1.cpp (original)
+++ cfe/trunk/test/SemaTemplate/variadic-class-template-1.cpp (removed)
@@ -1,4 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
-
-template<typename ... Args = int> struct S1 { }; // expected-error{{template parameter pack cannot have a default argument}}
-template<typename ... Args, typename T> struct S2 { }; // expected-error{{template parameter pack must be the last template parameter}}
Removed: cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp?rev=118384&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp (original)
+++ cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp (removed)
@@ -1,19 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
-
-// Type parameters packs
-template <typename ...> struct TS1 {}; // expected-note{{template parameter is declared here}}
-template struct TS1<>;
-template struct TS1<int>;
-template struct TS1<int, int>;
-template struct TS1<int, 10>; // expected-error{{template argument for template type parameter must be a type}}
-
-template <typename, typename ...> struct TS2 {}; // expected-note{{template is declared here}}
-template struct TS2<>; // expected-error{{too few template arguments for class template 'TS2'}}
-template struct TS2<int>;
-template struct TS2<int, int>;
-
-template <typename = int, typename ...> struct TS3 {}; // expected-note{{template parameter is declared here}}
-template struct TS3<>; // expected-note{{previous explicit instantiation is here}}
-template struct TS3<int>; // expected-error{{duplicate explicit instantiation of 'TS3}}
-template struct TS3<int, int>;
-template struct TS3<10>; // expected-error{{template argument for template type parameter must be a type}}
Removed: cfe/trunk/test/SemaTemplate/variadic-parse.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/variadic-parse.cpp?rev=118384&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/variadic-parse.cpp (original)
+++ cfe/trunk/test/SemaTemplate/variadic-parse.cpp (removed)
@@ -1,6 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
-
-// Parsing type parameter packs.
-template <typename ... Args> struct T1 {};
-template <typename ... > struct T2 {};
-
Removed: cfe/trunk/test/SemaTemplate/variadic-unsupported.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/variadic-unsupported.cpp?rev=118384&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/variadic-unsupported.cpp (original)
+++ cfe/trunk/test/SemaTemplate/variadic-unsupported.cpp (removed)
@@ -1,5 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-
-// Type parameter packs.
-template <typename ... > struct T1 {}; // expected-error{{variadic templates are only allowed in C++0x}}
-
Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=118385&r1=118384&r2=118385&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Sun Nov 7 17:05:16 2010
@@ -2720,8 +2720,8 @@
llvm::raw_svector_ostream OS(Str);
OS << ClassSpec->getNameAsString();
OS << TemplateSpecializationType::PrintTemplateArgumentList(
- ClassSpec->getTemplateArgs().getFlatArgumentList(),
- ClassSpec->getTemplateArgs().flat_size(),
+ ClassSpec->getTemplateArgs().data(),
+ ClassSpec->getTemplateArgs().size(),
Policy);
return createCXString(OS.str());
}
More information about the cfe-commits
mailing list