diff options
-rw-r--r-- | include/clang/AST/Type.h | 5 | ||||
-rw-r--r-- | lib/AST/ExprCXX.cpp | 16 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 24 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 37 |
5 files changed, 57 insertions, 35 deletions
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 5f5377414d..7eb332bd95 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -923,6 +923,11 @@ public: 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. // diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 5f908096bb..c394e476f8 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -728,15 +728,15 @@ CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const { // 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 @@ CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const { 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() { diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 52ee60b984..05e7fdc49e 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -415,6 +415,16 @@ const CXXRecordDecl *Type::getCXXRecordDeclForPointerType() const { 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 && diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 088ca96edd..997b8f8dcb 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1063,6 +1063,15 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S, 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 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg, 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); diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 2f36807659..cca14caa44 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -5336,19 +5336,16 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr( 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 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) BaseType = getDerived().TransformType(Old->getBaseType()); } - CXXRecordDecl *NamingClass = 0; NestedNameSpecifier *Qualifier = 0; if (Old->getQualifier()) { Qualifier @@ -5743,12 +5739,6 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) 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 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) 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()) { |