aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Type.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/Type.cpp')
-rw-r--r--lib/AST/Type.cpp161
1 files changed, 106 insertions, 55 deletions
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 5fb0178834ff..3608d34c691d 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -224,6 +224,8 @@ QualType Type::getPointeeType() const {
return OPT->getPointeeType();
if (const BlockPointerType *BPT = getAs<BlockPointerType>())
return BPT->getPointeeType();
+ if (const ReferenceType *RT = getAs<ReferenceType>())
+ return RT->getPointeeType();
return QualType();
}
@@ -791,40 +793,48 @@ bool EnumType::classof(const TagType *TT) {
return isa<EnumDecl>(TT->getDecl());
}
-bool
-TemplateSpecializationType::
-anyDependentTemplateArguments(const TemplateArgument *Args, unsigned NumArgs) {
- for (unsigned Idx = 0; Idx < NumArgs; ++Idx) {
- switch (Args[Idx].getKind()) {
- case TemplateArgument::Null:
- assert(false && "Should not have a NULL template argument");
- break;
-
- case TemplateArgument::Type:
- if (Args[Idx].getAsType()->isDependentType())
- return true;
- break;
-
- case TemplateArgument::Declaration:
- case TemplateArgument::Integral:
- // Never dependent
- break;
-
- case TemplateArgument::Expression:
- if (Args[Idx].getAsExpr()->isTypeDependent() ||
- Args[Idx].getAsExpr()->isValueDependent())
- return true;
- break;
-
- case TemplateArgument::Pack:
- assert(0 && "FIXME: Implement!");
- break;
- }
+static bool isDependent(const TemplateArgument &Arg) {
+ switch (Arg.getKind()) {
+ case TemplateArgument::Null:
+ assert(false && "Should not have a NULL template argument");
+ return false;
+
+ case TemplateArgument::Type:
+ return Arg.getAsType()->isDependentType();
+
+ case TemplateArgument::Declaration:
+ case TemplateArgument::Integral:
+ // Never dependent
+ return false;
+
+ case TemplateArgument::Expression:
+ return (Arg.getAsExpr()->isTypeDependent() ||
+ Arg.getAsExpr()->isValueDependent());
+
+ case TemplateArgument::Pack:
+ assert(0 && "FIXME: Implement!");
+ return false;
}
return false;
}
+bool TemplateSpecializationType::
+anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N) {
+ for (unsigned i = 0; i != N; ++i)
+ if (isDependent(Args[i].getArgument()))
+ return true;
+ return false;
+}
+
+bool TemplateSpecializationType::
+anyDependentTemplateArguments(const TemplateArgument *Args, unsigned N) {
+ for (unsigned i = 0; i != N; ++i)
+ if (isDependent(Args[i]))
+ return true;
+ return false;
+}
+
TemplateSpecializationType::
TemplateSpecializationType(ASTContext &Context, TemplateName T,
const TemplateArgument *Args,
@@ -1260,6 +1270,38 @@ void SubstTemplateTypeParmType::getAsStringInternal(std::string &InnerString, co
getReplacementType().getAsStringInternal(InnerString, Policy);
}
+static void PrintTemplateArgument(std::string &Buffer,
+ const TemplateArgument &Arg,
+ const PrintingPolicy &Policy) {
+ switch (Arg.getKind()) {
+ case TemplateArgument::Null:
+ assert(false && "Null template argument");
+ break;
+
+ case TemplateArgument::Type:
+ Arg.getAsType().getAsStringInternal(Buffer, Policy);
+ break;
+
+ case TemplateArgument::Declaration:
+ Buffer = cast<NamedDecl>(Arg.getAsDecl())->getNameAsString();
+ break;
+
+ case TemplateArgument::Integral:
+ Buffer = Arg.getAsIntegral()->toString(10, true);
+ break;
+
+ case TemplateArgument::Expression: {
+ llvm::raw_string_ostream s(Buffer);
+ Arg.getAsExpr()->printPretty(s, 0, Policy);
+ break;
+ }
+
+ case TemplateArgument::Pack:
+ assert(0 && "FIXME: Implement!");
+ break;
+ }
+}
+
std::string
TemplateSpecializationType::PrintTemplateArgumentList(
const TemplateArgument *Args,
@@ -1273,32 +1315,41 @@ TemplateSpecializationType::PrintTemplateArgumentList(
// Print the argument into a string.
std::string ArgString;
- switch (Args[Arg].getKind()) {
- case TemplateArgument::Null:
- assert(false && "Null template argument");
- break;
-
- case TemplateArgument::Type:
- Args[Arg].getAsType().getAsStringInternal(ArgString, Policy);
- break;
-
- case TemplateArgument::Declaration:
- ArgString = cast<NamedDecl>(Args[Arg].getAsDecl())->getNameAsString();
- break;
-
- case TemplateArgument::Integral:
- ArgString = Args[Arg].getAsIntegral()->toString(10, true);
- break;
-
- case TemplateArgument::Expression: {
- llvm::raw_string_ostream s(ArgString);
- Args[Arg].getAsExpr()->printPretty(s, 0, Policy);
- break;
- }
- case TemplateArgument::Pack:
- assert(0 && "FIXME: Implement!");
- break;
- }
+ PrintTemplateArgument(ArgString, Args[Arg], Policy);
+
+ // If this is the first argument and its string representation
+ // begins with the global scope specifier ('::foo'), add a space
+ // to avoid printing the diagraph '<:'.
+ if (!Arg && !ArgString.empty() && ArgString[0] == ':')
+ SpecString += ' ';
+
+ SpecString += ArgString;
+ }
+
+ // If the last character of our string is '>', add another space to
+ // keep the two '>''s separate tokens. We don't *have* to do this in
+ // C++0x, but it's still good hygiene.
+ if (SpecString[SpecString.size() - 1] == '>')
+ SpecString += ' ';
+
+ SpecString += '>';
+
+ return SpecString;
+}
+
+// Sadly, repeat all that with TemplateArgLoc.
+std::string TemplateSpecializationType::
+PrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs,
+ const PrintingPolicy &Policy) {
+ std::string SpecString;
+ SpecString += '<';
+ for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
+ if (Arg)
+ SpecString += ", ";
+
+ // Print the argument into a string.
+ std::string ArgString;
+ PrintTemplateArgument(ArgString, Args[Arg].getArgument(), Policy);
// If this is the first argument and its string representation
// begins with the global scope specifier ('::foo'), add a space