[cfe-commits] r102448 - in /cfe/trunk: include/clang/AST/Type.h lib/AST/ExprCXX.cpp lib/AST/Type.cpp lib/Sema/SemaExpr.cpp lib/Sema/TreeTransform.h

Douglas Gregor dgregor at apple.com
Tue Apr 27 11:19:34 PDT 2010


Author: dgregor
Date: Tue Apr 27 13:19:34 2010
New Revision: 102448

URL: http://llvm.org/viewvc/llvm-project?rev=102448&view=rev
Log:
During template	instantiation, set the naming class of
UnresolvedLookupExpr and UnresolvedMemberExpr by substituting the
naming class we computed when building the expression in the
template...

... which we didn't always do correctly. Teach
UnresolvedMemberExpr::getNamingClass() all about the new 
representation of injected-class-names in templates, so	that it	can
return a naming	class that is the current instantiation.

Also, when decomposing a template-id into its template name and its
arguments, be sure to set the naming class on the LookupResult
structure. 

Fixes PR6947 the right way.

Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/ExprCXX.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/TreeTransform.h

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=102448&r1=102447&r2=102448&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Tue Apr 27 13:19:34 2010
@@ -923,6 +923,11 @@
   const ObjCInterfaceType *getAsObjCQualifiedInterfaceType() const;
   const CXXRecordDecl *getCXXRecordDeclForPointerType() const;
 
+  /// \brief Retrieves the CXXRecordDecl that this type refers to, either
+  /// because the type is a RecordType or because it is the injected-class-name 
+  /// type of a class template or class template partial specialization.
+  CXXRecordDecl *getAsCXXRecordDecl() const;
+  
   // Member-template getAs<specific type>'.  This scheme will eventually
   // replace the specific getAsXXXX methods above.
   //

Modified: cfe/trunk/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=102448&r1=102447&r2=102448&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Tue Apr 27 13:19:34 2010
@@ -728,15 +728,15 @@
   // If there was a nested name specifier, it names the naming class.
   // It can't be dependent: after all, we were actually able to do the
   // lookup.
-  const RecordType *RT;
+  CXXRecordDecl *Record = 0;
   if (getQualifier()) {
     Type *T = getQualifier()->getAsType();
     assert(T && "qualifier in member expression does not name type");
-    RT = T->getAs<RecordType>();
-    assert(RT && "qualifier in member expression does not name record");
-
+    Record = T->getAsCXXRecordDecl();
+    assert(Record && "qualifier in member expression does not name record");
+  }
   // Otherwise the naming class must have been the base class.
-  } else {
+  else {
     QualType BaseType = getBaseType().getNonReferenceType();
     if (isArrow()) {
       const PointerType *PT = BaseType->getAs<PointerType>();
@@ -744,11 +744,11 @@
       BaseType = PT->getPointeeType();
     }
     
-    RT = BaseType->getAs<RecordType>();
-    assert(RT && "base of member expression does not name record");
+    Record = BaseType->getAsCXXRecordDecl();
+    assert(Record && "base of member expression does not name record");
   }
   
-  return cast<CXXRecordDecl>(RT->getDecl());
+  return Record;
 }
 
 Stmt::child_iterator UnresolvedMemberExpr::child_begin() {

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=102448&r1=102447&r2=102448&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Tue Apr 27 13:19:34 2010
@@ -415,6 +415,16 @@
   return 0;
 }
 
+CXXRecordDecl *Type::getAsCXXRecordDecl() const {
+  if (const RecordType *RT = getAs<RecordType>())
+    return dyn_cast<CXXRecordDecl>(RT->getDecl());
+  else if (const InjectedClassNameType *Injected
+                                  = getAs<InjectedClassNameType>())
+    return Injected->getDecl();
+  
+  return 0;
+}
+
 bool Type::isIntegerType() const {
   if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
     return BT->getKind() >= BuiltinType::Bool &&

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=102448&r1=102447&r2=102448&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Apr 27 13:19:34 2010
@@ -1063,6 +1063,15 @@
   if (TemplateArgs) {
     // Just re-use the lookup done by isTemplateName.
     DecomposeTemplateName(R, Id);
+
+    // Re-derive the naming class.
+    if (SS.isSet()) {
+      NestedNameSpecifier *Qualifier
+        = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+      if (const Type *Ty = Qualifier->getAsType())
+        if (CXXRecordDecl *NamingClass = Ty->getAsCXXRecordDecl())
+          R.setNamingClass(NamingClass);
+    }
   } else {
     bool IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl());
     LookupParsedName(R, S, &SS, !IvarLookupFollowUp);
@@ -3231,6 +3240,21 @@
     if (TemplateArgs) {
       // Re-use the lookup done for the template name.
       DecomposeTemplateName(R, Id);
+      
+      // Re-derive the naming class.
+      if (SS.isSet()) {
+        NestedNameSpecifier *Qualifier
+        = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+        if (const Type *Ty = Qualifier->getAsType())
+          if (CXXRecordDecl *NamingClass = Ty->getAsCXXRecordDecl())
+            R.setNamingClass(NamingClass);
+      } else {
+        QualType BaseType = Base->getType();
+        if (const PointerType *Ptr = BaseType->getAs<PointerType>())
+          BaseType = Ptr->getPointeeType();
+        if (CXXRecordDecl *NamingClass = BaseType->getAsCXXRecordDecl())
+          R.setNamingClass(NamingClass);
+      }
     } else {
       Result = LookupMemberExpr(R, Base, IsArrow, OpLoc,
                                 SS, ObjCImpDecl);

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=102448&r1=102447&r2=102448&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Tue Apr 27 13:19:34 2010
@@ -5336,19 +5336,16 @@
     
     SS.setScopeRep(Qualifier);
     SS.setRange(Old->getQualifierRange());
-    
-    // If this nested-name-specifier refers to a class type, that is the
-    // naming class.
-    if (const Type *NamedType = Qualifier->getAsType())
-      if (const RecordType *NamedRecord = NamedType->getAs<RecordType>())
-        R.setNamingClass(cast<CXXRecordDecl>(NamedRecord->getDecl()));
-  } else if (Old->getNamingClass()) {
+  } 
+  
+  if (Old->getNamingClass()) {
     CXXRecordDecl *NamingClass
       = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
                                                             Old->getNameLoc(),
                                                         Old->getNamingClass()));
     if (!NamingClass)
       return SemaRef.ExprError();
+    
     R.setNamingClass(NamingClass);
   }
 
@@ -5735,7 +5732,6 @@
     BaseType = getDerived().TransformType(Old->getBaseType());
   }
 
-  CXXRecordDecl *NamingClass = 0;
   NestedNameSpecifier *Qualifier = 0;
   if (Old->getQualifier()) {
     Qualifier
@@ -5743,12 +5739,6 @@
                                                   Old->getQualifierRange());
     if (Qualifier == 0)
       return SemaRef.ExprError();
-    
-    // If this nested-name-specifier refers to a class type, that is the
-    // naming class.
-    if (const Type *NamedType = Qualifier->getAsType())
-      if (const RecordType *NamedRecord = NamedType->getAs<RecordType>())
-        NamingClass = cast<CXXRecordDecl>(NamedRecord->getDecl());
   }
 
   LookupResult R(SemaRef, Old->getMemberName(), Old->getMemberLoc(),
@@ -5783,24 +5773,17 @@
 
   R.resolveKind();
 
-  // Determine the naming class, if we haven't already.
-  if (!NamingClass) {
-    QualType T = BaseType;
-    if (const PointerType *PointerTy = T->getAs<PointerType>())
-      T = PointerTy->getPointeeType();
-    if (const RecordType *NamedRecord = T->getAs<RecordType>())
-      NamingClass = cast<CXXRecordDecl>(NamedRecord->getDecl());    
-  }
-  
-  if (!NamingClass && Old->getNamingClass()) {
-    NamingClass = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
+  // Determine the naming class.
+  if (!Old->getNamingClass()) {
+    CXXRecordDecl *NamingClass 
+      = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
                                                           Old->getMemberLoc(),
                                                         Old->getNamingClass()));
     if (!NamingClass)
       return SemaRef.ExprError();
-  }
-  if (NamingClass)
+    
     R.setNamingClass(NamingClass);
+  }
   
   TemplateArgumentListInfo TransArgs;
   if (Old->hasExplicitTemplateArgs()) {





More information about the cfe-commits mailing list