[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