[cfe-commits] r105880 - in /cfe/trunk: include/clang/AST/DeclTemplate.h lib/AST/DeclTemplate.cpp lib/Sema/SemaTemplate.cpp

Abramo Bagnara abramo.bagnara at gmail.com
Sat Jun 12 00:44:57 PDT 2010


Author: abramo
Date: Sat Jun 12 02:44:57 2010
New Revision: 105880

URL: http://llvm.org/viewvc/llvm-project?rev=105880&view=rev
Log:
Don't omit class explicit instantiation from AST.

Modified:
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/lib/AST/DeclTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=105880&r1=105879&r2=105880&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Sat Jun 12 02:44:57 2010
@@ -901,9 +901,22 @@
   llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
     SpecializedTemplate;
 
-  /// \brief The type-as-written of an explicit template specialization.
+  /// \brief Further info for explicit template specialization/instantiation.
+  struct ExplicitSpecializationInfo {
+    /// \brief The type-as-written.
+    TypeSourceInfo *TypeAsWritten;
+    /// \brief The location of the extern keyword.
+    SourceLocation ExternLoc;
+    /// \brief The location of the template keyword.
+    SourceLocation TemplateKeywordLoc;
+
+    ExplicitSpecializationInfo()
+      : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
+  };
+
+  /// \brief Further info for explicit template specialization/instantiation.
   /// Does not apply to implicit specializations.
-  TypeSourceInfo *TypeAsWritten;
+  ExplicitSpecializationInfo *ExplicitInfo;
 
   /// \brief The template arguments used to describe this specialization.
   TemplateArgumentList TemplateArgs;
@@ -1018,13 +1031,33 @@
   /// \brief Sets the type of this specialization as it was written by
   /// the user. This will be a class template specialization type.
   void setTypeAsWritten(TypeSourceInfo *T) {
-    TypeAsWritten = T;
+    if (!ExplicitInfo) ExplicitInfo = new ExplicitSpecializationInfo;
+    ExplicitInfo->TypeAsWritten = T;
   }
-
   /// \brief Gets the type of this specialization as it was written by
   /// the user, if it was so written.
   TypeSourceInfo *getTypeAsWritten() const {
-    return TypeAsWritten;
+    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
+  }
+
+  /// \brief Gets the location of the extern keyword, if present.
+  SourceLocation getExternLoc() const {
+    return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
+  }
+  /// \brief Sets the location of the extern keyword.
+  void setExternLoc(SourceLocation Loc) {
+    if (!ExplicitInfo) ExplicitInfo = new ExplicitSpecializationInfo;
+    ExplicitInfo->ExternLoc = Loc;
+  }
+
+  /// \brief Sets the location of the template keyword.
+  void setTemplateKeywordLoc(SourceLocation Loc) {
+    if (!ExplicitInfo) ExplicitInfo = new ExplicitSpecializationInfo;
+    ExplicitInfo->TemplateKeywordLoc = Loc;
+  }
+  /// \brief Gets the location of the template keyword, if present.
+  SourceLocation getTemplateKeywordLoc() const {
+    return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
   }
 
   void Profile(llvm::FoldingSetNodeID &ID) const {

Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=105880&r1=105879&r2=105880&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Sat Jun 12 02:44:57 2010
@@ -426,7 +426,7 @@
                   SpecializedTemplate->getIdentifier(),
                   PrevDecl),
     SpecializedTemplate(SpecializedTemplate),
-    TypeAsWritten(0),
+    ExplicitInfo(0),
     TemplateArgs(Context, Builder, /*TakeArgs=*/true),
     SpecializationKind(TSK_Undeclared) {
 }
@@ -449,6 +449,8 @@
 }
 
 void ClassTemplateSpecializationDecl::Destroy(ASTContext &C) {
+  delete ExplicitInfo;
+
   if (SpecializedPartialSpecialization *PartialSpec
         = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
     C.Deallocate(PartialSpec);

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=105880&r1=105879&r2=105880&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Sat Jun 12 02:44:57 2010
@@ -3981,8 +3981,10 @@
   TypeSourceInfo *WrittenTy
     = Context.getTemplateSpecializationTypeInfo(Name, TemplateNameLoc,
                                                 TemplateArgs, CanonType);
-  if (TUK != TUK_Friend)
+  if (TUK != TUK_Friend) {
     Specialization->setTypeAsWritten(WrittenTy);
+    Specialization->setTemplateKeywordLoc(KWLoc);
+  }
   TemplateArgsIn.release();
 
   // C++ [temp.expl.spec]p9:
@@ -4076,7 +4078,7 @@
 /// \param PrevPointOfInstantiation if valid, indicates where the previus 
 /// declaration was instantiated (either implicitly or explicitly).
 ///
-/// \param SuppressNew will be set to true to indicate that the new 
+/// \param HasNoEffect will be set to true to indicate that the new 
 /// specialization or instantiation has no effect and should be ignored.
 ///
 /// \returns true if there was an error that should prevent the introduction of
@@ -4087,8 +4089,8 @@
                                              NamedDecl *PrevDecl,
                                              TemplateSpecializationKind PrevTSK,
                                         SourceLocation PrevPointOfInstantiation,
-                                             bool &SuppressNew) {
-  SuppressNew = false;
+                                             bool &HasNoEffect) {
+  HasNoEffect = false;
   
   switch (NewTSK) {
   case TSK_Undeclared:
@@ -4145,7 +4147,7 @@
     switch (PrevTSK) {
     case TSK_ExplicitInstantiationDeclaration:
       // This explicit instantiation declaration is redundant (that's okay).
-      SuppressNew = true;
+      HasNoEffect = true;
       return false;
         
     case TSK_Undeclared:
@@ -4160,7 +4162,7 @@
       //   of a template appears after a declaration of an explicit 
       //   specialization for that template, the explicit instantiation has no
       //   effect.
-      SuppressNew = true;
+      HasNoEffect = true;
       return false;
         
     case TSK_ExplicitInstantiationDefinition:
@@ -4174,7 +4176,7 @@
            diag::note_explicit_instantiation_definition_here);
       assert(PrevPointOfInstantiation.isValid() &&
              "Explicit instantiation without point of instantiation?");
-      SuppressNew = true;
+      HasNoEffect = true;
       return false;
     }
     break;
@@ -4203,7 +4205,7 @@
         Diag(PrevDecl->getLocation(),
              diag::note_previous_template_specialization);
       }
-      SuppressNew = true;
+      HasNoEffect = true;
       return false;
         
     case TSK_ExplicitInstantiationDeclaration:
@@ -4220,7 +4222,7 @@
         << PrevDecl;
       Diag(PrevPointOfInstantiation, 
            diag::note_previous_explicit_instantiation);
-      SuppressNew = true;
+      HasNoEffect = true;
       return false;        
     }
     break;
@@ -4369,14 +4371,14 @@
     = Specialization->getTemplateSpecializationInfo();
   assert(SpecInfo && "Function template specialization info missing?");
 
-  bool SuppressNew = false;
+  bool HasNoEffect = false;
   if (!isFriend &&
       CheckSpecializationInstantiationRedecl(FD->getLocation(),
                                              TSK_ExplicitSpecialization,
                                              Specialization,
                                    SpecInfo->getTemplateSpecializationKind(),
                                          SpecInfo->getPointOfInstantiation(),
-                                             SuppressNew))
+                                             HasNoEffect))
     return true;
   
   // Mark the prior declaration as an explicit specialization, so that later
@@ -4503,13 +4505,13 @@
   //   use occurs; no diagnostic is required.
   assert(MSInfo && "Member specialization info missing?");
 
-  bool SuppressNew = false;
+  bool HasNoEffect = false;
   if (CheckSpecializationInstantiationRedecl(Member->getLocation(),
                                              TSK_ExplicitSpecialization,
                                              Instantiation,
                                      MSInfo->getTemplateSpecializationKind(),
                                            MSInfo->getPointOfInstantiation(),
-                                             SuppressNew))
+                                             HasNoEffect))
     return true;
   
   // Check the scope of this explicit specialization.
@@ -4711,6 +4713,9 @@
   ClassTemplateSpecializationDecl *PrevDecl
     = ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
 
+  TemplateSpecializationKind PrevDecl_TSK
+    = PrevDecl ? PrevDecl->getTemplateSpecializationKind() : TSK_Undeclared;
+
   // C++0x [temp.explicit]p2:
   //   [...] An explicit instantiation shall appear in an enclosing
   //   namespace of its template. [...]
@@ -4722,31 +4727,31 @@
   ClassTemplateSpecializationDecl *Specialization = 0;
 
   bool ReusedDecl = false;
+  bool HasNoEffect = false;
   if (PrevDecl) {
-    bool SuppressNew = false;
     if (CheckSpecializationInstantiationRedecl(TemplateNameLoc, TSK,
-                                               PrevDecl, 
-                                              PrevDecl->getSpecializationKind(), 
+                                               PrevDecl, PrevDecl_TSK,
                                             PrevDecl->getPointOfInstantiation(),
-                                               SuppressNew))
+                                               HasNoEffect))
       return DeclPtrTy::make(PrevDecl);
 
-    if (SuppressNew)
-      return DeclPtrTy::make(PrevDecl);
-    
-    if (PrevDecl->getSpecializationKind() == TSK_ImplicitInstantiation ||
-        PrevDecl->getSpecializationKind() == TSK_Undeclared) {
+    // Even though HasNoEffect == true means that this explicit instantiation
+    // has no effect on semantics, we go on to put its syntax in the AST.
+
+    if (PrevDecl_TSK == TSK_ImplicitInstantiation ||
+        PrevDecl_TSK == TSK_Undeclared) {
       // Since the only prior class template specialization with these
       // arguments was referenced but not declared, reuse that
-      // declaration node as our own, updating its source location to
-      // reflect our new declaration.
+      // declaration node as our own, updating the source location
+      // for the template name to reflect our new declaration.
+      // (Other source locations will be updated later.)
       Specialization = PrevDecl;
       Specialization->setLocation(TemplateNameLoc);
       PrevDecl = 0;
       ReusedDecl = true;
     }
   }
-  
+
   if (!Specialization) {
     // Create a new class template specialization declaration node for
     // this explicit specialization.
@@ -4758,15 +4763,16 @@
                                                 Converted, PrevDecl);
     SetNestedNameSpecifier(Specialization, SS);
 
-    if (PrevDecl) {
-      // Remove the previous declaration from the folding set, since we want
-      // to introduce a new declaration.
-      ClassTemplate->getSpecializations().RemoveNode(PrevDecl);
-      ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
-    } 
-    
-    // Insert the new specialization.
-    ClassTemplate->getSpecializations().InsertNode(Specialization, InsertPos);
+    if (!HasNoEffect) {
+      if (PrevDecl) {
+        // Remove the previous declaration from the folding set, since we want
+        // to introduce a new declaration.
+        ClassTemplate->getSpecializations().RemoveNode(PrevDecl);
+        ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+      }
+      // Insert the new specialization.
+      ClassTemplate->getSpecializations().InsertNode(Specialization, InsertPos);
+    }
   }
 
   // Build the fully-sugared type for this explicit instantiation as
@@ -4783,12 +4789,21 @@
   Specialization->setTypeAsWritten(WrittenTy);
   TemplateArgsIn.release();
 
-  if (!ReusedDecl) {
-    // Add the explicit instantiation into its lexical context. However,
-    // since explicit instantiations are never found by name lookup, we
-    // just put it into the declaration context directly.
-    Specialization->setLexicalDeclContext(CurContext);
-    CurContext->addDecl(Specialization);
+  // Set source locations for keywords.
+  Specialization->setExternLoc(ExternLoc);
+  Specialization->setTemplateKeywordLoc(TemplateLoc);
+
+  // Add the explicit instantiation into its lexical context. However,
+  // since explicit instantiations are never found by name lookup, we
+  // just put it into the declaration context directly.
+  Specialization->setLexicalDeclContext(CurContext);
+  CurContext->addDecl(Specialization);
+
+  // Syntax is now OK, so return if it has no other effect on semantics.
+  if (HasNoEffect) {
+    // Set the template specialization kind.
+    Specialization->setTemplateSpecializationKind(TSK);
+    return DeclPtrTy::make(Specialization);
   }
 
   // C++ [temp.explicit]p3:
@@ -4803,8 +4818,10 @@
                                               Specialization->getDefinition());
   if (!Def)
     InstantiateClassTemplateSpecialization(TemplateNameLoc, Specialization, TSK);
-  else if (TSK == TSK_ExplicitInstantiationDefinition)
+  else if (TSK == TSK_ExplicitInstantiationDefinition) {
     MarkVTableUsed(TemplateNameLoc, Specialization, true);
+    Specialization->setPointOfInstantiation(Def->getPointOfInstantiation());
+  }
 
   // Instantiate the members of this class template specialization.
   Def = cast_or_null<ClassTemplateSpecializationDecl>(
@@ -4821,6 +4838,8 @@
     InstantiateClassTemplateSpecializationMembers(TemplateNameLoc, Def, TSK);
   }
 
+  // Set the template specialization kind.
+  Specialization->setTemplateSpecializationKind(TSK);
   return DeclPtrTy::make(Specialization);
 }
 
@@ -4898,15 +4917,15 @@
     PrevDecl = Record;
   if (PrevDecl) {
     MemberSpecializationInfo *MSInfo = PrevDecl->getMemberSpecializationInfo();
-    bool SuppressNew = false;
+    bool HasNoEffect = false;
     assert(MSInfo && "No member specialization information?");
     if (CheckSpecializationInstantiationRedecl(TemplateLoc, TSK, 
                                                PrevDecl,
                                         MSInfo->getTemplateSpecializationKind(),
                                              MSInfo->getPointOfInstantiation(), 
-                                               SuppressNew))
+                                               HasNoEffect))
       return true;
-    if (SuppressNew)
+    if (HasNoEffect)
       return TagD;
   }
   
@@ -5055,13 +5074,13 @@
     // Verify that it is okay to explicitly instantiate here.
     MemberSpecializationInfo *MSInfo = Prev->getMemberSpecializationInfo();
     assert(MSInfo && "Missing static data member specialization info?");
-    bool SuppressNew = false;
+    bool HasNoEffect = false;
     if (CheckSpecializationInstantiationRedecl(D.getIdentifierLoc(), TSK, Prev,
                                         MSInfo->getTemplateSpecializationKind(),
                                               MSInfo->getPointOfInstantiation(), 
-                                               SuppressNew))
+                                               HasNoEffect))
       return true;
-    if (SuppressNew)
+    if (HasNoEffect)
       return DeclPtrTy();
     
     // Instantiate static data member.
@@ -5158,17 +5177,17 @@
     PrevDecl = Specialization;
 
   if (PrevDecl) {
-    bool SuppressNew = false;
+    bool HasNoEffect = false;
     if (CheckSpecializationInstantiationRedecl(D.getIdentifierLoc(), TSK,
                                                PrevDecl, 
                                      PrevDecl->getTemplateSpecializationKind(), 
                                           PrevDecl->getPointOfInstantiation(),
-                                               SuppressNew))
+                                               HasNoEffect))
       return true;
     
     // FIXME: We may still want to build some representation of this
     // explicit specialization.
-    if (SuppressNew)
+    if (HasNoEffect)
       return DeclPtrTy();
   }
 





More information about the cfe-commits mailing list