[cfe-commits] r126593 - in /cfe/trunk: include/clang/Sema/Sema.h lib/AST/ASTContext.cpp lib/AST/ItaniumMangle.cpp lib/AST/Type.cpp lib/Parse/ParseExprCXX.cpp lib/Parse/Parser.cpp lib/Sema/SemaCXXScopeSpec.cpp lib/Sema/TreeTransform.h
Douglas Gregor
dgregor at apple.com
Sun Feb 27 16:04:36 PST 2011
Author: dgregor
Date: Sun Feb 27 18:04:36 2011
New Revision: 126593
URL: http://llvm.org/viewvc/llvm-project?rev=126593&view=rev
Log:
When we encounter a dependent template name within a
nested-name-specifier, e.g.,
T::template apply<U>::
represent the dependent template name specialization as a
DependentTemplateSpecializationType, rather than a
TemplateSpecializationType with a dependent TemplateName.
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/ItaniumMangle.cpp
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
cfe/trunk/lib/Sema/TreeTransform.h
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=126593&r1=126592&r2=126593&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Sun Feb 27 18:04:36 2011
@@ -2659,25 +2659,41 @@
ParsedType ObjectType,
bool EnteringContext);
- /// \brief The parser has parsed a nested-name-specifier 'type::'.
+ /// \brief The parser has parsed a nested-name-specifier
+ /// 'template[opt] template-name < template-args >::'.
///
/// \param S The scope in which this nested-name-specifier occurs.
///
- /// \param Type The type, which will be a template specialization
- /// type, preceding the '::'.
- ///
- /// \param CCLoc The location of the '::'.
+ /// \param TemplateLoc The location of the 'template' keyword, if any.
///
/// \param SS The nested-name-specifier, which is both an input
/// parameter (the nested-name-specifier before this type) and an
/// output parameter (containing the full nested-name-specifier,
/// including this new type).
+ ///
+ /// \param TemplateLoc the location of the 'template' keyword, if any.
+ /// \param TemplateName The template name.
+ /// \param TemplateNameLoc The location of the template name.
+ /// \param LAngleLoc The location of the opening angle bracket ('<').
+ /// \param TemplateArgs The template arguments.
+ /// \param RAngleLoc The location of the closing angle bracket ('>').
+ /// \param CCLoc The location of the '::'.
+
+ /// \param EnteringContext Whether we're entering the context of the
+ /// nested-name-specifier.
+ ///
///
/// \returns true if an error occurred, false otherwise.
bool ActOnCXXNestedNameSpecifier(Scope *S,
- ParsedType Type,
+ SourceLocation TemplateLoc,
+ CXXScopeSpec &SS,
+ TemplateTy Template,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgs,
+ SourceLocation RAngleLoc,
SourceLocation CCLoc,
- CXXScopeSpec &SS);
+ bool EnteringContext);
/// \brief Given a C++ nested-name-specifier, produce an annotation value
/// that the parser can use later to reconstruct the given
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=126593&r1=126592&r2=126593&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sun Feb 27 18:04:36 2011
@@ -2377,7 +2377,8 @@
const IdentifierInfo *Name,
unsigned NumArgs,
const TemplateArgument *Args) const {
- assert(NNS->isDependent() && "nested-name-specifier must be dependent");
+ assert((!NNS || NNS->isDependent()) &&
+ "nested-name-specifier must be dependent");
llvm::FoldingSetNodeID ID;
DependentTemplateSpecializationType::Profile(ID, *this, Keyword, NNS,
@@ -3014,10 +3015,11 @@
= T->getAs<DependentTemplateSpecializationType>()) {
NestedNameSpecifier *Prefix
= getCanonicalNestedNameSpecifier(DTST->getQualifier());
- TemplateName Name
- = getDependentTemplateName(Prefix, DTST->getIdentifier());
- T = getTemplateSpecializationType(Name,
- DTST->getArgs(), DTST->getNumArgs());
+
+ T = getDependentTemplateSpecializationType(DTST->getKeyword(),
+ Prefix, DTST->getIdentifier(),
+ DTST->getNumArgs(),
+ DTST->getArgs());
T = getCanonicalType(T);
}
Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=126593&r1=126592&r2=126593&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Sun Feb 27 18:04:36 2011
@@ -625,6 +625,17 @@
TST->getNumArgs());
addSubstitution(QualType(TST, 0));
}
+ } else if (const DependentTemplateSpecializationType *DTST
+ = dyn_cast<DependentTemplateSpecializationType>(QTy)) {
+ TemplateName Template
+ = getASTContext().getDependentTemplateName(DTST->getQualifier(),
+ DTST->getIdentifier());
+ mangleTemplatePrefix(Template);
+
+ // FIXME: GCC does not appear to mangle the template arguments when
+ // the template in question is a dependent template name. Should we
+ // emulate that badness?
+ mangleTemplateArgs(Template, DTST->getArgs(), DTST->getNumArgs());
} else {
// We use the QualType mangle type variant here because it handles
// substitutions.
@@ -1596,7 +1607,7 @@
}
void CXXNameMangler::mangleType(const DependentTemplateSpecializationType *T) {
- // Dependently-scoped template types are always nested
+ // Dependently-scoped template types are nested if they have a prefix.
Out << 'N';
// TODO: avoid making this TemplateName.
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=126593&r1=126592&r2=126593&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Sun Feb 27 18:04:36 2011
@@ -1040,9 +1040,9 @@
QualType Canon)
: TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true,
/*VariablyModified=*/false,
- NNS->containsUnexpandedParameterPack()),
+ NNS && NNS->containsUnexpandedParameterPack()),
NNS(NNS), Name(Name), NumArgs(NumArgs) {
- assert(NNS && NNS->isDependent() &&
+ assert((!NNS || NNS->isDependent()) &&
"DependentTemplateSpecializatonType requires dependent qualifier");
for (unsigned I = 0; I != NumArgs; ++I) {
if (Args[I].containsUnexpandedParameterPack())
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=126593&r1=126592&r2=126593&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Sun Feb 27 18:04:36 2011
@@ -199,29 +199,32 @@
if (TemplateId->Kind == TNK_Type_template ||
TemplateId->Kind == TNK_Dependent_template_name) {
- AnnotateTemplateIdTokenAsType(&SS);
-
- assert(Tok.is(tok::annot_typename) &&
- "AnnotateTemplateIdTokenAsType isn't working");
- Token TypeToken = Tok;
+ // Consume the template-id token.
ConsumeToken();
+
assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
SourceLocation CCLoc = ConsumeToken();
if (!HasScopeSpecifier)
HasScopeSpecifier = true;
-
- if (ParsedType T = getTypeAnnotation(TypeToken)) {
- if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), T, CCLoc, SS))
- SS.SetInvalid(SourceRange(SS.getBeginLoc(), CCLoc));
-
- continue;
- } else {
- SourceLocation Start = SS.getBeginLoc().isValid()? SS.getBeginLoc()
- : CCLoc;
- SS.SetInvalid(SourceRange(Start, CCLoc));
- }
+ ASTTemplateArgsPtr TemplateArgsPtr(Actions,
+ TemplateId->getTemplateArgs(),
+ TemplateId->NumArgs);
+
+ if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(),
+ /*FIXME:*/SourceLocation(),
+ SS,
+ TemplateId->Template,
+ TemplateId->TemplateNameLoc,
+ TemplateId->LAngleLoc,
+ TemplateArgsPtr,
+ TemplateId->RAngleLoc,
+ CCLoc,
+ EnteringContext))
+ SS.SetInvalid(SourceRange(SS.getBeginLoc(), CCLoc));
+
+ TemplateId->Destroy();
continue;
}
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=126593&r1=126592&r2=126593&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Sun Feb 27 18:04:36 2011
@@ -1062,6 +1062,7 @@
TemplateId->LAngleLoc,
TemplateArgsPtr,
TemplateId->RAngleLoc);
+ TemplateId->Destroy();
} else {
Diag(Tok, diag::err_expected_type_name_after_typename)
<< SS.getRange();
Modified: cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp?rev=126593&r1=126592&r2=126593&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp Sun Feb 27 18:04:36 2011
@@ -641,20 +641,73 @@
}
bool Sema::ActOnCXXNestedNameSpecifier(Scope *S,
- ParsedType Type,
+ SourceLocation TemplateLoc,
+ CXXScopeSpec &SS,
+ TemplateTy Template,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgsIn,
+ SourceLocation RAngleLoc,
SourceLocation CCLoc,
- CXXScopeSpec &SS) {
+ bool EnteringContext) {
if (SS.isInvalid())
return true;
- TypeSourceInfo *TSInfo;
- QualType T = GetTypeFromParser(Type, &TSInfo);
+ // Translate the parser's template argument list in our AST format.
+ TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
+ translateTemplateArguments(TemplateArgsIn, TemplateArgs);
+
+ if (DependentTemplateName *DTN = Template.get().getAsDependentTemplateName()){
+ // Handle a dependent template specialization for which we cannot resolve
+ // the template name.
+ assert(DTN->getQualifier()
+ == static_cast<NestedNameSpecifier*>(SS.getScopeRep()));
+ QualType T = Context.getDependentTemplateSpecializationType(ETK_None,
+ DTN->getQualifier(),
+ DTN->getIdentifier(),
+ TemplateArgs);
+
+ // Create source-location information for this type.
+ TypeLocBuilder Builder;
+ DependentTemplateSpecializationTypeLoc SpecTL
+ = Builder.push<DependentTemplateSpecializationTypeLoc>(T);
+ SpecTL.setLAngleLoc(LAngleLoc);
+ SpecTL.setRAngleLoc(RAngleLoc);
+ SpecTL.setKeywordLoc(SourceLocation());
+ SpecTL.setNameLoc(TemplateNameLoc);
+ for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
+ SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
+
+ SS.Extend(Context, TemplateLoc, Builder.getTypeLocInContext(Context, T),
+ CCLoc);
+ return false;
+ }
+
+ // We were able to resolve the template name to an actual template.
+ // Build an appropriate nested-name-specifier.
+ QualType T = CheckTemplateIdType(Template.get(), TemplateNameLoc,
+ TemplateArgs);
if (T.isNull())
return true;
- assert(TSInfo && "Not TypeSourceInfo in nested-name-specifier?");
- // FIXME: location of the 'template' keyword?
- SS.Extend(Context, SourceLocation(), TSInfo->getTypeLoc(), CCLoc);
+ // FIXME: Template aliases will need to check the resulting type to make
+ // sure that it's either dependent or a tag type.
+
+ // Provide source-location information for the template specialization
+ // type.
+ TypeLocBuilder Builder;
+ TemplateSpecializationTypeLoc SpecTL
+ = Builder.push<TemplateSpecializationTypeLoc>(T);
+
+ SpecTL.setLAngleLoc(LAngleLoc);
+ SpecTL.setRAngleLoc(RAngleLoc);
+ SpecTL.setTemplateNameLoc(TemplateNameLoc);
+ for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
+ SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
+
+
+ SS.Extend(Context, TemplateLoc, Builder.getTypeLocInContext(Context, T),
+ CCLoc);
return false;
}
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=126593&r1=126592&r2=126593&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Sun Feb 27 18:04:36 2011
@@ -754,6 +754,9 @@
getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
if (T.isNull()) return QualType();
+ if (Keyword == ETK_None)
+ return T;
+
// NOTE: NNS is already recorded in template specialization type T.
return SemaRef.Context.getElaboratedType(Keyword, /*NNS=*/0, T);
}
More information about the cfe-commits
mailing list