[cfe-commits] r78286 - in /cfe/trunk/lib/Sema: SemaExpr.cpp SemaTemplateInstantiate.cpp TreeTransform.h

Douglas Gregor dgregor at apple.com
Wed Aug 5 22:28:42 PDT 2009


Author: dgregor
Date: Thu Aug  6 00:28:30 2009
New Revision: 78286

URL: http://llvm.org/viewvc/llvm-project?rev=78286&view=rev
Log:
Implement transformation of nested-name-specifiers within the general
tree transformation. Template instantiation uses this general
transformation rather than implementing its own transformation.

Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/TreeTransform.h

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=78286&r1=78285&r2=78286&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Aug  6 00:28:30 2009
@@ -2181,8 +2181,7 @@
       = LookupQualifiedName(DC, DeclarationName(&Member),  
                             LookupMemberName, false);
 
-    if (SS && SS->isSet())
-    {
+    if (SS && SS->isSet()) {
       QualType BaseTypeCanon 
         = Context.getCanonicalType(BaseType).getUnqualifiedType();
       QualType MemberTypeCanon 

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=78286&r1=78285&r2=78286&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Aug  6 00:28:30 2009
@@ -324,10 +324,6 @@
     /// this declaration.
     Decl *TransformDecl(Decl *D);
     
-    /// \brief Transform the given nested-name-specifier by instantiating it.
-    NestedNameSpecifier *TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
-                                                      SourceRange Range);
-    
     /// \brief Transform the given template name by instantiating it.
     TemplateName TransformTemplateName(TemplateName Template);
     
@@ -345,12 +341,6 @@
   return SemaRef.InstantiateCurrentDeclRef(cast_or_null<NamedDecl>(D));
 }
 
-NestedNameSpecifier *
-TemplateInstantiator::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
-                                                   SourceRange Range) {
-  return getSema().InstantiateNestedNameSpecifier(NNS, Range, TemplateArgs);
-}
-
 TemplateName 
 TemplateInstantiator::TransformTemplateName(TemplateName Template) {
   return getSema().InstantiateTemplateName(Template, /*FIXME*/Loc, 
@@ -722,59 +712,9 @@
 Sema::InstantiateNestedNameSpecifier(NestedNameSpecifier *NNS,
                                      SourceRange Range,
                                      const TemplateArgumentList &TemplateArgs) {
-  // Instantiate the prefix of this nested name specifier.
-  NestedNameSpecifier *Prefix = NNS->getPrefix();
-  if (Prefix) {
-    Prefix = InstantiateNestedNameSpecifier(Prefix, Range, TemplateArgs);
-    if (!Prefix)
-      return 0;
-  }
-
-  switch (NNS->getKind()) {
-  case NestedNameSpecifier::Identifier: {
-    assert(Prefix && 
-           "Can't have an identifier nested-name-specifier with no prefix");
-    CXXScopeSpec SS;
-    // FIXME: The source location information is all wrong.
-    SS.setRange(Range);
-    SS.setScopeRep(Prefix);
-    return static_cast<NestedNameSpecifier *>(
-                                 ActOnCXXNestedNameSpecifier(0, SS,
-                                                             Range.getEnd(),
-                                                             Range.getEnd(),
-                                                    *NNS->getAsIdentifier()));
-    break;
-  }
-
-  case NestedNameSpecifier::Namespace:
-  case NestedNameSpecifier::Global:
-    return NNS;
-    
-  case NestedNameSpecifier::TypeSpecWithTemplate:
-  case NestedNameSpecifier::TypeSpec: {
-    QualType T = QualType(NNS->getAsType(), 0);
-    if (!T->isDependentType())
-      return NNS;
-
-    T = InstantiateType(T, TemplateArgs, Range.getBegin(), DeclarationName());
-    if (T.isNull())
-      return 0;
-
-    if (T->isDependentType() || T->isRecordType() ||
-        (getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
-      assert(T.getCVRQualifiers() == 0 && "Can't get cv-qualifiers here");
-      return NestedNameSpecifier::Create(Context, Prefix, 
-                 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
-                                         T.getTypePtr());
-    }
-
-    Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
-    return 0;
-  }
-  }
-
-  // Required to silence a GCC warning
-  return 0;
+  TemplateInstantiator Instantiator(*this, TemplateArgs, Range.getBegin(),
+                                    DeclarationName());
+  return Instantiator.TransformNestedNameSpecifier(NNS, Range);
 }
 
 TemplateName

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=78286&r1=78285&r2=78286&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Thu Aug  6 00:28:30 2009
@@ -14,6 +14,7 @@
 #define LLVM_CLANG_SEMA_TREETRANSFORM_H
 
 #include "Sema.h"
+#include "clang/Sema/SemaDiagnostic.h"
 #include <algorithm>
 
 namespace clang {
@@ -156,12 +157,15 @@
   /// \brief Transform the given declaration, which is referenced from a type
   /// or expression.
   ///
-  /// Subclasses must override this.
-  Decl *TransformDecl(Decl *D);
+  /// By default, acts as the identity function on declarations. Subclasses
+  /// may override this function to provide alternate behavior.
+  Decl *TransformDecl(Decl *D) { return D; }
   
   /// \brief Transform the given nested-name-specifier.
   ///
-  /// Subclasses must override this.
+  /// By default, transforms all of the types and declarations within the 
+  /// nested-name-specifier. Subclasses may override this function to provide
+  /// alternate behavior.
   NestedNameSpecifier *TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
                                                     SourceRange Range);
   
@@ -397,10 +401,98 @@
                                const IdentifierInfo *Id) {
     return SemaRef.CheckTypenameType(NNS, *Id,
                                   SourceRange(getDerived().getBaseLocation()));
-  }    
+  }
+  
+  /// \brief Build a new nested-name-specifier given the prefix and an
+  /// identifier that names the next step in the nested-name-specifier.
+  ///
+  /// By default, performs semantic analysis when building the new
+  /// nested-name-specifier. Subclasses may override this routine to provide
+  /// different behavior.
+  NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+                                                  SourceRange Range,
+                                                  IdentifierInfo &II);
+
+  /// \brief Build a new nested-name-specifier given the prefix and the
+  /// namespace named in the next step in the nested-name-specifier.
+  ///
+  /// By default, performs semantic analysis when building the new
+  /// nested-name-specifier. Subclasses may override this routine to provide
+  /// different behavior.
+  NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+                                                  SourceRange Range,
+                                                  NamespaceDecl *NS);
+
+  /// \brief Build a new nested-name-specifier given the prefix and the
+  /// type named in the next step in the nested-name-specifier.
+  ///
+  /// By default, performs semantic analysis when building the new
+  /// nested-name-specifier. Subclasses may override this routine to provide
+  /// different behavior.
+  NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+                                                  SourceRange Range,
+                                                  bool TemplateKW,
+                                                  QualType T);
 };
   
 template<typename Derived>
+NestedNameSpecifier *
+TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
+                                                     SourceRange Range) {
+  // Instantiate the prefix of this nested name specifier.
+  NestedNameSpecifier *Prefix = NNS->getPrefix();
+  if (Prefix) {
+    Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range);
+    if (!Prefix)
+      return 0;
+  }
+  
+  switch (NNS->getKind()) {
+  case NestedNameSpecifier::Identifier:
+    assert(Prefix && 
+           "Can't have an identifier nested-name-specifier with no prefix");
+    if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix())
+      return NNS;
+      
+    return getDerived().RebuildNestedNameSpecifier(Prefix, Range, 
+                                                   *NNS->getAsIdentifier());
+      
+  case NestedNameSpecifier::Namespace: {
+    NamespaceDecl *NS 
+      = cast_or_null<NamespaceDecl>(
+                            getDerived().TransformDecl(NNS->getAsNamespace()));
+    if (!getDerived().AlwaysRebuild() && 
+        Prefix == NNS->getPrefix() &&
+        NS == NNS->getAsNamespace())
+      return NNS;
+    
+    return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
+  }
+      
+  case NestedNameSpecifier::Global:
+    // There is no meaningful transformation that one could perform on the
+    // global scope.
+    return NNS;
+      
+  case NestedNameSpecifier::TypeSpecWithTemplate:
+  case NestedNameSpecifier::TypeSpec: {
+    QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
+    if (!getDerived().AlwaysRebuild() &&
+        Prefix == NNS->getPrefix() &&
+        T == QualType(NNS->getAsType(), 0))
+      return NNS;
+    
+    return getDerived().RebuildNestedNameSpecifier(Prefix, Range, 
+                  NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,    
+                                                   T);
+  }
+  }
+  
+  // Required to silence a GCC warning
+  return 0;  
+}
+
+template<typename Derived>
 TemplateArgument 
 TreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
   switch (Arg.getKind()) {
@@ -1212,6 +1304,45 @@
                                      SourceLocation());  
 }
   
+template<typename Derived>
+NestedNameSpecifier *
+TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+                                                   SourceRange Range,
+                                                   IdentifierInfo &II) {
+  CXXScopeSpec SS;
+  // FIXME: The source location information is all wrong.
+  SS.setRange(Range);
+  SS.setScopeRep(Prefix);
+  return static_cast<NestedNameSpecifier *>(
+                    SemaRef.ActOnCXXNestedNameSpecifier(0, SS, Range.getEnd(), 
+                                                        Range.getEnd(), II));
+}
+
+template<typename Derived>
+NestedNameSpecifier *
+TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+                                                   SourceRange Range,
+                                                   NamespaceDecl *NS) {
+  return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
+}
+
+template<typename Derived>
+NestedNameSpecifier *
+TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+                                                   SourceRange Range,
+                                                   bool TemplateKW,
+                                                   QualType T) {
+  if (T->isDependentType() || T->isRecordType() ||
+      (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
+    assert(T.getCVRQualifiers() == 0 && "Can't get cv-qualifiers here");
+    return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
+                                       T.getTypePtr());
+  }
+  
+  SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
+  return 0;
+}
+  
 } // end namespace clang
 
 #endif // LLVM_CLANG_SEMA_TREETRANSFORM_H





More information about the cfe-commits mailing list