diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ComparisonCategories.cpp | 61 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprAgg.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 8 |
4 files changed, 35 insertions, 42 deletions
diff --git a/clang/lib/AST/ComparisonCategories.cpp b/clang/lib/AST/ComparisonCategories.cpp index c2bb3c653e7..87f51facc59 100644 --- a/clang/lib/AST/ComparisonCategories.cpp +++ b/clang/lib/AST/ComparisonCategories.cpp @@ -20,34 +20,32 @@ using namespace clang; -/// Attempt to determine the integer value used to represent the comparison -/// category result by evaluating the initializer for the specified VarDecl as -/// a constant expression and retreiving the value of the classes first -/// (and only) field. -/// -/// Note: The STL types are expected to have the form: -/// struct X { T value; }; -/// where T is an integral or enumeration type. -static bool evaluateIntValue(const ASTContext &Ctx, - ComparisonCategoryInfo::ValueInfo *Info) { - if (Info->hasValidIntValue()) +bool ComparisonCategoryInfo::ValueInfo::hasValidIntValue() const { + assert(VD && "must have var decl"); + if (!VD->checkInitIsICE()) return false; // Before we attempt to get the value of the first field, ensure that we // actually have one (and only one) field. - auto *Record = Info->VD->getType()->getAsCXXRecordDecl(); + auto *Record = VD->getType()->getAsCXXRecordDecl(); if (std::distance(Record->field_begin(), Record->field_end()) != 1 || !Record->field_begin()->getType()->isIntegralOrEnumerationType()) - return true; + return false; - Expr::EvalResult Result; - if (!Info->VD->hasInit() || - !Info->VD->getInit()->EvaluateAsRValue(Result, Ctx)) - return true; + return true; +} - assert(Result.Val.isStruct()); - Info->setIntValue(Result.Val.getStructField(0).getInt()); - return false; +/// Attempt to determine the integer value used to represent the comparison +/// category result by evaluating the initializer for the specified VarDecl as +/// a constant expression and retreiving the value of the class's first +/// (and only) field. +/// +/// Note: The STL types are expected to have the form: +/// struct X { T value; }; +/// where T is an integral or enumeration type. +llvm::APSInt ComparisonCategoryInfo::ValueInfo::getIntValue() const { + assert(hasValidIntValue() && "must have a valid value"); + return VD->evaluateValue()->getStructField(0).getInt(); } ComparisonCategoryInfo::ValueInfo *ComparisonCategoryInfo::lookupValueInfo( @@ -55,24 +53,17 @@ ComparisonCategoryInfo::ValueInfo *ComparisonCategoryInfo::lookupValueInfo( // Check if we already have a cache entry for this value. auto It = llvm::find_if( Objects, [&](ValueInfo const &Info) { return Info.Kind == ValueKind; }); + if (It != Objects.end()) + return &(*It); // We don't have a cached result. Lookup the variable declaration and create // a new entry representing it. - if (It == Objects.end()) { - DeclContextLookupResult Lookup = Record->getCanonicalDecl()->lookup( - &Ctx.Idents.get(ComparisonCategories::getResultString(ValueKind))); - if (Lookup.size() != 1 || !isa<VarDecl>(Lookup.front())) - return nullptr; - Objects.emplace_back(ValueKind, cast<VarDecl>(Lookup.front())); - It = Objects.end() - 1; - } - assert(It != Objects.end()); - // Success! Attempt to update the int value in case the variables initializer - // wasn't present the last time we were here. - ValueInfo *Info = &(*It); - evaluateIntValue(Ctx, Info); - - return Info; + DeclContextLookupResult Lookup = Record->getCanonicalDecl()->lookup( + &Ctx.Idents.get(ComparisonCategories::getResultString(ValueKind))); + if (Lookup.size() != 1 || !isa<VarDecl>(Lookup.front())) + return nullptr; + Objects.emplace_back(ValueKind, cast<VarDecl>(Lookup.front())); + return &Objects.back(); } static const NamespaceDecl *lookupStdNamespace(const ASTContext &Ctx, diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 23d74dae4e3..a736beb96bb 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -956,7 +956,7 @@ void AggExprEmitter::VisitBinCmp(const BinaryOperator *E) { if (!ArgTy->isIntegralOrEnumerationType() && !ArgTy->isRealFloatingType() && !ArgTy->isNullPtrType() && !ArgTy->isPointerType() && !ArgTy->isMemberPointerType() && !ArgTy->isAnyComplexType()) { - return CGF.ErrorUnsupported(E, "aggregate three-way comparisoaoeun"); + return CGF.ErrorUnsupported(E, "aggregate three-way comparison"); } bool IsComplex = ArgTy->isAnyComplexType(); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index fb168957bd7..caa0b746439 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -8938,8 +8938,10 @@ QualType Sema::CheckComparisonCategoryType(ComparisonCategoryType Kind, // If lookup failed if (!Info) { + auto NameForDiags = + llvm::Twine("std::") + ComparisonCategories::getCategoryString(Kind); Diag(Loc, diag::err_implied_comparison_category_type_not_found) - << ComparisonCategories::getCategoryString(Kind); + << NameForDiags.str(); return QualType(); } @@ -8947,7 +8949,7 @@ QualType Sema::CheckComparisonCategoryType(ComparisonCategoryType Kind, assert(Info->Record); // Update the Record decl in case we encountered a forward declaration on our - // first pass. FIXME(EricWF): This is a bit of a hack. + // first pass. FIXME: This is a bit of a hack. if (Info->Record->hasDefinition()) Info->Record = Info->Record->getDefinition(); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 177cfd7354a..8522c04e73b 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -9757,12 +9757,12 @@ static bool checkThreeWayNarrowingConversion(Sema &S, QualType ToType, Expr *E, SourceLocation Loc) { // Check for a narrowing implicit conversion. StandardConversionSequence SCS; + SCS.setAsIdentityConversion(); SCS.setToType(0, FromType); SCS.setToType(1, ToType); - if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) { - auto CastK = ICE->getCastKind(); - SCS.Second = castKindToImplicitConversionKind(CastK); - } + if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) + SCS.Second = castKindToImplicitConversionKind(ICE->getCastKind()); + APValue PreNarrowingValue; QualType PreNarrowingType; switch (SCS.getNarrowingKind(S.Context, E, PreNarrowingValue, |