diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 42 | ||||
| -rw-r--r-- | clang/lib/Sema/Sema.h | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaCXXCast.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 16 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaType.cpp | 39 | 
5 files changed, 56 insertions, 45 deletions
| diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 75af89ee96a..2e724495756 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2339,6 +2339,48 @@ QualType ASTContext::getUnqualifiedArrayType(QualType T,                                      SourceRange());  } +/// UnwrapSimilarPointerTypes - If T1 and T2 are pointer types  that +/// may be similar (C++ 4.4), replaces T1 and T2 with the type that +/// they point to and return true. If T1 and T2 aren't pointer types +/// or pointer-to-member types, or if they are not similar at this +/// level, returns false and leaves T1 and T2 unchanged. Top-level +/// qualifiers on T1 and T2 are ignored. This function will typically +/// be called in a loop that successively "unwraps" pointer and +/// pointer-to-member types to compare them at each level. +bool ASTContext::UnwrapSimilarPointerTypes(QualType &T1, QualType &T2) { +  const PointerType *T1PtrType = T1->getAs<PointerType>(), +                    *T2PtrType = T2->getAs<PointerType>(); +  if (T1PtrType && T2PtrType) { +    T1 = T1PtrType->getPointeeType(); +    T2 = T2PtrType->getPointeeType(); +    return true; +  } +   +  const MemberPointerType *T1MPType = T1->getAs<MemberPointerType>(), +                          *T2MPType = T2->getAs<MemberPointerType>(); +  if (T1MPType && T2MPType &&  +      hasSameUnqualifiedType(QualType(T1MPType->getClass(), 0),  +                             QualType(T2MPType->getClass(), 0))) { +    T1 = T1MPType->getPointeeType(); +    T2 = T2MPType->getPointeeType(); +    return true; +  } +   +  if (getLangOptions().ObjC1) { +    const ObjCObjectPointerType *T1OPType = T1->getAs<ObjCObjectPointerType>(), +                                *T2OPType = T2->getAs<ObjCObjectPointerType>(); +    if (T1OPType && T2OPType) { +      T1 = T1OPType->getPointeeType(); +      T2 = T2OPType->getPointeeType(); +      return true; +    } +  } +   +  // FIXME: Block pointers, too? +   +  return false; +} +  DeclarationName ASTContext::getNameForTemplate(TemplateName Name) {    if (TemplateDecl *TD = Name.getAsTemplateDecl())      return TD->getDeclName(); diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 25f4e9d6c18..48b8d05d918 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -769,8 +769,6 @@ public:        const FunctionProtoType *Target, SourceLocation TargetLoc,        const FunctionProtoType *Source, SourceLocation SourceLoc); -  bool UnwrapSimilarPointerTypes(QualType& T1, QualType& T2); -    virtual TypeResult ActOnTypeName(Scope *S, Declarator &D);    bool RequireCompleteType(SourceLocation Loc, QualType T, diff --git a/clang/lib/Sema/SemaCXXCast.cpp b/clang/lib/Sema/SemaCXXCast.cpp index 5485bb3e17a..16f0af14d27 100644 --- a/clang/lib/Sema/SemaCXXCast.cpp +++ b/clang/lib/Sema/SemaCXXCast.cpp @@ -1019,7 +1019,7 @@ static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,    // in multi-level pointers may change, but the level count must be the same,    // as must be the final pointee type.    while (SrcType != DestType && -         Self.UnwrapSimilarPointerTypes(SrcType, DestType)) { +         Self.Context.UnwrapSimilarPointerTypes(SrcType, DestType)) {      Qualifiers Quals;      SrcType = Self.Context.getUnqualifiedArrayType(SrcType, Quals);      DestType = Self.Context.getUnqualifiedArrayType(DestType, Quals); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index d746ec3f6dc..721c68f6c1d 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1785,7 +1785,7 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType) {    //   in multi-level pointers, subject to the following rules: [...]    bool PreviousToQualsIncludeConst = true;    bool UnwrappedAnyPointer = false; -  while (UnwrapSimilarPointerTypes(FromType, ToType)) { +  while (Context.UnwrapSimilarPointerTypes(FromType, ToType)) {      // Within each iteration of the loop, we check the qualifiers to      // determine if this still looks like a qualification      // conversion. Then, if all is well, we unwrap one more level of @@ -2073,6 +2073,16 @@ Sema::CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,    return ImplicitConversionSequence::Indistinguishable;  } +static bool hasSimilarType(ASTContext &Context, QualType T1, QualType T2) { +  while (Context.UnwrapSimilarPointerTypes(T1, T2)) { +    Qualifiers Quals; +    T1 = Context.getUnqualifiedArrayType(T1, Quals); +    T2 = Context.getUnqualifiedArrayType(T2, Quals);     +  } +   +  return Context.hasSameUnqualifiedType(T1, T2); +} +    // Per 13.3.3.2p3, compare the given standard conversion sequences to  // determine if one is a proper subset of the other.  static ImplicitConversionSequence::CompareKind @@ -2098,7 +2108,7 @@ compareStandardConversionSubsets(ASTContext &Context,        Result = ImplicitConversionSequence::Worse;      else        return ImplicitConversionSequence::Indistinguishable; -  } else if (!Context.hasSameType(SCS1.getToType(1), SCS2.getToType(1))) +  } else if (!hasSimilarType(Context, SCS1.getToType(1), SCS2.getToType(1)))      return ImplicitConversionSequence::Indistinguishable;    if (SCS1.Third == SCS2.Third) { @@ -2305,7 +2315,7 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,    ImplicitConversionSequence::CompareKind Result      = ImplicitConversionSequence::Indistinguishable; -  while (UnwrapSimilarPointerTypes(T1, T2)) { +  while (Context.UnwrapSimilarPointerTypes(T1, T2)) {      // Within each iteration of the loop, we check the qualifiers to      // determine if this still looks like a qualification      // conversion. Then, if all is well, we unwrap one more level of diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 8242f61897e..8327fd26864 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1611,45 +1611,6 @@ void LocInfoType::getAsStringInternal(std::string &Str,           " GetTypeFromParser");  } -/// UnwrapSimilarPointerTypes - If T1 and T2 are pointer types  that -/// may be similar (C++ 4.4), replaces T1 and T2 with the type that -/// they point to and return true. If T1 and T2 aren't pointer types -/// or pointer-to-member types, or if they are not similar at this -/// level, returns false and leaves T1 and T2 unchanged. Top-level -/// qualifiers on T1 and T2 are ignored. This function will typically -/// be called in a loop that successively "unwraps" pointer and -/// pointer-to-member types to compare them at each level. -bool Sema::UnwrapSimilarPointerTypes(QualType& T1, QualType& T2) { -  const PointerType *T1PtrType = T1->getAs<PointerType>(), -                    *T2PtrType = T2->getAs<PointerType>(); -  if (T1PtrType && T2PtrType) { -    T1 = T1PtrType->getPointeeType(); -    T2 = T2PtrType->getPointeeType(); -    return true; -  } - -  const MemberPointerType *T1MPType = T1->getAs<MemberPointerType>(), -                          *T2MPType = T2->getAs<MemberPointerType>(); -  if (T1MPType && T2MPType && -      Context.getCanonicalType(T1MPType->getClass()) == -      Context.getCanonicalType(T2MPType->getClass())) { -    T1 = T1MPType->getPointeeType(); -    T2 = T2MPType->getPointeeType(); -    return true; -  } - -  if (getLangOptions().ObjC1) { -    const ObjCObjectPointerType *T1OPType = T1->getAs<ObjCObjectPointerType>(), -                                *T2OPType = T2->getAs<ObjCObjectPointerType>(); -    if (T1OPType && T2OPType) { -      T1 = T1OPType->getPointeeType(); -      T2 = T2OPType->getPointeeType(); -      return true; -    } -  } -  return false; -} -  Sema::TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) {    // C99 6.7.6: Type names have no identifier.  This is already validated by    // the parser. | 

