diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-15 00:41:48 +0000 | 
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-15 00:41:48 +0000 | 
| commit | 79aa513231c48b31732a5354cd01a278a79656e1 (patch) | |
| tree | 43a4b6f6ce8296193c5f19684e840a5949636163 /clang/lib | |
| parent | 3904590ba8c8eb68699696c8545caaaa9144854a (diff) | |
| download | bcm5719-llvm-79aa513231c48b31732a5354cd01a278a79656e1.tar.gz bcm5719-llvm-79aa513231c48b31732a5354cd01a278a79656e1.zip  | |
Minor optimization to constant evaluation: don't bother computing expr source
locations for diagnostics we're not going to emit, and don't track the subobject
designator outside C++11 (since we're not going to use it anyway).
This seems to give about a 0.5% speedup on 403.gcc/combine.c, but the results
were sufficiently noisy that I can't reject the null hypothesis.
llvm-svn: 152761
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 138 | 
1 files changed, 74 insertions, 64 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 7d65cf585b5..d507ed34193 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -480,9 +480,18 @@ namespace {        return OptionalDiagnostic();      } +    OptionalDiagnostic Diag(const Expr *E, diag::kind DiagId +                              = diag::note_invalid_subexpr_in_const_expr, +                            unsigned ExtraNotes = 0) { +      if (EvalStatus.Diag) +        return Diag(E->getExprLoc(), DiagId, ExtraNotes); +      return OptionalDiagnostic(); +    } +      /// Diagnose that the evaluation does not produce a C++11 core constant      /// expression. -    OptionalDiagnostic CCEDiag(SourceLocation Loc, diag::kind DiagId +    template<typename LocArg> +    OptionalDiagnostic CCEDiag(LocArg Loc, diag::kind DiagId                                   = diag::note_invalid_subexpr_in_const_expr,                                 unsigned ExtraNotes = 0) {        // Don't override a previous diagnostic. @@ -556,7 +565,7 @@ bool SubobjectDesignator::checkSubobject(EvalInfo &Info, const Expr *E,    if (Invalid)      return false;    if (isOnePastTheEnd()) { -    Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_past_end_subobject) +    Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)        << CSK;      setInvalid();      return false; @@ -567,11 +576,11 @@ bool SubobjectDesignator::checkSubobject(EvalInfo &Info, const Expr *E,  void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,                                                      const Expr *E, uint64_t N) {    if (MostDerivedPathLength == Entries.size() && MostDerivedArraySize) -    Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_array_index) +    Info.CCEDiag(E, diag::note_constexpr_array_index)        << static_cast<int>(N) << /*array*/ 0        << static_cast<unsigned>(MostDerivedArraySize);    else -    Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_array_index) +    Info.CCEDiag(E, diag::note_constexpr_array_index)        << static_cast<int>(N) << /*non-array*/ 1;    setInvalid();  } @@ -730,7 +739,7 @@ namespace {        if (Designator.Invalid)          return false;        if (!Base) { -        Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_null_subobject) +        Info.CCEDiag(E, diag::note_constexpr_null_subobject)            << CSK;          Designator.setInvalid();          return false; @@ -741,27 +750,30 @@ namespace {      // Check this LValue refers to an object. If not, set the designator to be      // invalid and emit a diagnostic.      bool checkSubobject(EvalInfo &Info, const Expr *E, CheckSubobjectKind CSK) { +      // Outside C++11, do not build a designator referring to a subobject of +      // any object: we won't use such a designator for anything. +      if (!Info.getLangOpts().CPlusPlus0x) +        Designator.setInvalid();        return checkNullPointer(Info, E, CSK) &&               Designator.checkSubobject(Info, E, CSK);      }      void addDecl(EvalInfo &Info, const Expr *E,                   const Decl *D, bool Virtual = false) { -      checkSubobject(Info, E, isa<FieldDecl>(D) ? CSK_Field : CSK_Base); -      Designator.addDeclUnchecked(D, Virtual); +      if (checkSubobject(Info, E, isa<FieldDecl>(D) ? CSK_Field : CSK_Base)) +        Designator.addDeclUnchecked(D, Virtual);      }      void addArray(EvalInfo &Info, const Expr *E, const ConstantArrayType *CAT) { -      checkSubobject(Info, E, CSK_ArrayToPointer); -      Designator.addArrayUnchecked(CAT); +      if (checkSubobject(Info, E, CSK_ArrayToPointer)) +        Designator.addArrayUnchecked(CAT);      }      void addComplex(EvalInfo &Info, const Expr *E, QualType EltTy, bool Imag) { -      checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real); -      Designator.addComplexUnchecked(EltTy, Imag); +      if (checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real)) +        Designator.addComplexUnchecked(EltTy, Imag);      }      void adjustIndex(EvalInfo &Info, const Expr *E, uint64_t N) { -      if (!checkNullPointer(Info, E, CSK_ArrayIndex)) -        return; -      Designator.adjustIndex(Info, E, N); +      if (checkNullPointer(Info, E, CSK_ArrayIndex)) +        Designator.adjustIndex(Info, E, N);      }    }; @@ -1020,10 +1032,10 @@ static bool CheckLiteralType(EvalInfo &Info, const Expr *E) {    // Prvalue constant expressions must be of literal types.    if (Info.getLangOpts().CPlusPlus0x) -    Info.Diag(E->getExprLoc(), diag::note_constexpr_nonliteral) +    Info.Diag(E, diag::note_constexpr_nonliteral)        << E->getType();    else -    Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr); +    Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);    return false;  } @@ -1155,7 +1167,7 @@ static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result,  template<typename T>  static bool HandleOverflow(EvalInfo &Info, const Expr *E,                             const T &SrcValue, QualType DestType) { -  Info.Diag(E->getExprLoc(), diag::note_constexpr_overflow) +  Info.Diag(E, diag::note_constexpr_overflow)      << SrcValue << DestType;    return false;  } @@ -1240,7 +1252,7 @@ static bool EvalAndBitcastToAPInt(EvalInfo &Info, const Expr *E,        } else {          // Don't try to handle vectors of anything other than int or float          // (not sure if it's possible to hit this case). -        Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr); +        Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);          return false;        }        unsigned BaseEltSize = EltAsInt.getBitWidth(); @@ -1253,7 +1265,7 @@ static bool EvalAndBitcastToAPInt(EvalInfo &Info, const Expr *E,    }    // Give up if the input isn't an int, float, or vector.  For example, we    // reject "(v4i16)(intptr_t)&a". -  Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr); +  Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);    return false;  } @@ -1414,7 +1426,7 @@ static bool EvaluateVarDeclInit(EvalInfo &Info, const Expr *E,      if (Info.CheckingPotentialConstantExpression)        return false;      if (!Frame || !Frame->Arguments) { -      Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr); +      Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);        return false;      }      Result = Frame->Arguments[PVD->getFunctionScopeIndex()]; @@ -1427,7 +1439,7 @@ static bool EvaluateVarDeclInit(EvalInfo &Info, const Expr *E,      // If we're checking a potential constant expression, the variable could be      // initialized later.      if (!Info.CheckingPotentialConstantExpression) -      Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr); +      Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);      return false;    } @@ -1441,7 +1453,7 @@ static bool EvaluateVarDeclInit(EvalInfo &Info, const Expr *E,    // Never evaluate the initializer of a weak variable. We can't be sure that    // this is the definition which will be used.    if (VD->isWeak()) { -    Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr); +    Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);      return false;    } @@ -1449,13 +1461,13 @@ static bool EvaluateVarDeclInit(EvalInfo &Info, const Expr *E,    // this in the cases where it matters for conformance.    llvm::SmallVector<PartialDiagnosticAt, 8> Notes;    if (!VD->evaluateValue(Notes)) { -    Info.Diag(E->getExprLoc(), diag::note_constexpr_var_init_non_constant, +    Info.Diag(E, diag::note_constexpr_var_init_non_constant,                Notes.size() + 1) << VD;      Info.Note(VD->getLocation(), diag::note_declared_at);      Info.addNotes(Notes);      return false;    } else if (!VD->checkInitIsICE()) { -    Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_var_init_non_constant, +    Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant,                   Notes.size() + 1) << VD;      Info.Note(VD->getLocation(), diag::note_declared_at);      Info.addNotes(Notes); @@ -1507,7 +1519,7 @@ static bool ExtractSubobject(EvalInfo &Info, const Expr *E,      // A diagnostic will have already been produced.      return false;    if (Sub.isOnePastTheEnd()) { -    Info.Diag(E->getExprLoc(), Info.getLangOpts().CPlusPlus0x ? +    Info.Diag(E, Info.getLangOpts().CPlusPlus0x ?                  (unsigned)diag::note_constexpr_read_past_end :                  (unsigned)diag::note_invalid_subexpr_in_const_expr);      return false; @@ -1529,7 +1541,7 @@ static bool ExtractSubobject(EvalInfo &Info, const Expr *E,        if (CAT->getSize().ule(Index)) {          // Note, it should not be possible to form a pointer with a valid          // designator which points more than one past the end of the array. -        Info.Diag(E->getExprLoc(), Info.getLangOpts().CPlusPlus0x ? +        Info.Diag(E, Info.getLangOpts().CPlusPlus0x ?                      (unsigned)diag::note_constexpr_read_past_end :                      (unsigned)diag::note_invalid_subexpr_in_const_expr);          return false; @@ -1551,7 +1563,7 @@ static bool ExtractSubobject(EvalInfo &Info, const Expr *E,        // Next subobject is a complex number.        uint64_t Index = Sub.Entries[I].ArrayIndex;        if (Index > 1) { -        Info.Diag(E->getExprLoc(), Info.getLangOpts().CPlusPlus0x ? +        Info.Diag(E, Info.getLangOpts().CPlusPlus0x ?                      (unsigned)diag::note_constexpr_read_past_end :                      (unsigned)diag::note_invalid_subexpr_in_const_expr);          return false; @@ -1568,7 +1580,7 @@ static bool ExtractSubobject(EvalInfo &Info, const Expr *E,        return true;      } else if (const FieldDecl *Field = getAsField(Sub.Entries[I])) {        if (Field->isMutable()) { -        Info.Diag(E->getExprLoc(), diag::note_constexpr_ltor_mutable, 1) +        Info.Diag(E, diag::note_constexpr_ltor_mutable, 1)            << Field;          Info.Note(Field->getLocation(), diag::note_declared_at);          return false; @@ -1580,8 +1592,7 @@ static bool ExtractSubobject(EvalInfo &Info, const Expr *E,          const FieldDecl *UnionField = O->getUnionField();          if (!UnionField ||              UnionField->getCanonicalDecl() != Field->getCanonicalDecl()) { -          Info.Diag(E->getExprLoc(), -                    diag::note_constexpr_read_inactive_union_member) +          Info.Diag(E, diag::note_constexpr_read_inactive_union_member)              << Field << !UnionField << UnionField;            return false;          } @@ -1593,11 +1604,11 @@ static bool ExtractSubobject(EvalInfo &Info, const Expr *E,        if (ObjType.isVolatileQualified()) {          if (Info.getLangOpts().CPlusPlus) {            // FIXME: Include a description of the path to the volatile subobject. -          Info.Diag(E->getExprLoc(), diag::note_constexpr_ltor_volatile_obj, 1) +          Info.Diag(E, diag::note_constexpr_ltor_volatile_obj, 1)              << 2 << Field;            Info.Note(Field->getLocation(), diag::note_declared_at);          } else { -          Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr); +          Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);          }          return false;        } @@ -1611,7 +1622,7 @@ static bool ExtractSubobject(EvalInfo &Info, const Expr *E,      if (O->isUninit()) {        if (!Info.CheckingPotentialConstantExpression) -        Info.Diag(E->getExprLoc(), diag::note_constexpr_read_uninit); +        Info.Diag(E, diag::note_constexpr_read_uninit);        return false;      }    } @@ -1702,11 +1713,10 @@ static bool HandleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv,      return false;    const Expr *Base = LVal.Base.dyn_cast<const Expr*>(); -  SourceLocation Loc = Conv->getExprLoc();    if (!LVal.Base) {      // FIXME: Indirection through a null pointer deserves a specific diagnostic. -    Info.Diag(Loc, diag::note_invalid_subexpr_in_const_expr); +    Info.Diag(Conv, diag::note_invalid_subexpr_in_const_expr);      return false;    } @@ -1714,7 +1724,7 @@ static bool HandleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv,    if (LVal.CallIndex) {      Frame = Info.getCallFrame(LVal.CallIndex);      if (!Frame) { -      Info.Diag(Loc, diag::note_constexpr_lifetime_ended, 1) << !Base; +      Info.Diag(Conv, diag::note_constexpr_lifetime_ended, 1) << !Base;        NoteLValueLocation(Info, LVal.Base);        return false;      } @@ -1726,9 +1736,9 @@ static bool HandleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv,    // semantics.    if (Type.isVolatileQualified()) {      if (Info.getLangOpts().CPlusPlus) -      Info.Diag(Loc, diag::note_constexpr_ltor_volatile_type) << Type; +      Info.Diag(Conv, diag::note_constexpr_ltor_volatile_type) << Type;      else -      Info.Diag(Loc); +      Info.Diag(Conv);      return false;    } @@ -1742,7 +1752,7 @@ static bool HandleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv,      if (const VarDecl *VDef = VD->getDefinition(Info.Ctx))        VD = VDef;      if (!VD || VD->isInvalidDecl()) { -      Info.Diag(Loc); +      Info.Diag(Conv);        return false;      } @@ -1751,10 +1761,10 @@ static bool HandleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv,      QualType VT = VD->getType();      if (VT.isVolatileQualified()) {        if (Info.getLangOpts().CPlusPlus) { -        Info.Diag(Loc, diag::note_constexpr_ltor_volatile_obj, 1) << 1 << VD; +        Info.Diag(Conv, diag::note_constexpr_ltor_volatile_obj, 1) << 1 << VD;          Info.Note(VD->getLocation(), diag::note_declared_at);        } else { -        Info.Diag(Loc); +        Info.Diag(Conv);        }        return false;      } @@ -1765,10 +1775,10 @@ static bool HandleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv,        } else if (VT->isIntegralOrEnumerationType()) {          if (!VT.isConstQualified()) {            if (Info.getLangOpts().CPlusPlus) { -            Info.Diag(Loc, diag::note_constexpr_ltor_non_const_int, 1) << VD; +            Info.Diag(Conv, diag::note_constexpr_ltor_non_const_int, 1) << VD;              Info.Note(VD->getLocation(), diag::note_declared_at);            } else { -            Info.Diag(Loc); +            Info.Diag(Conv);            }            return false;          } @@ -1777,18 +1787,18 @@ static bool HandleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv,          // static const data members of such types (supported as an extension)          // more useful.          if (Info.getLangOpts().CPlusPlus0x) { -          Info.CCEDiag(Loc, diag::note_constexpr_ltor_non_constexpr, 1) << VD; +          Info.CCEDiag(Conv, diag::note_constexpr_ltor_non_constexpr, 1) << VD;            Info.Note(VD->getLocation(), diag::note_declared_at);          } else { -          Info.CCEDiag(Loc); +          Info.CCEDiag(Conv);          }        } else {          // FIXME: Allow folding of values of any literal type in all languages.          if (Info.getLangOpts().CPlusPlus0x) { -          Info.Diag(Loc, diag::note_constexpr_ltor_non_constexpr, 1) << VD; +          Info.Diag(Conv, diag::note_constexpr_ltor_non_constexpr, 1) << VD;            Info.Note(VD->getLocation(), diag::note_declared_at);          } else { -          Info.Diag(Loc); +          Info.Diag(Conv);          }          return false;        } @@ -1812,7 +1822,7 @@ static bool HandleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv,      if (unsigned CallIndex = RVal.getLValueCallIndex()) {        Frame = Info.getCallFrame(CallIndex);        if (!Frame) { -        Info.Diag(Loc, diag::note_constexpr_lifetime_ended, 1) << !Base; +        Info.Diag(Conv, diag::note_constexpr_lifetime_ended, 1) << !Base;          NoteLValueLocation(Info, RVal.getLValueBase());          return false;        } @@ -1824,10 +1834,10 @@ static bool HandleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv,    // Volatile temporary objects cannot be read in constant expressions.    if (Base->getType().isVolatileQualified()) {      if (Info.getLangOpts().CPlusPlus) { -      Info.Diag(Loc, diag::note_constexpr_ltor_volatile_obj, 1) << 0; +      Info.Diag(Conv, diag::note_constexpr_ltor_volatile_obj, 1) << 0;        Info.Note(Base->getExprLoc(), diag::note_constexpr_temporary_here);      } else { -      Info.Diag(Loc); +      Info.Diag(Conv);      }      return false;    } @@ -1850,7 +1860,7 @@ static bool HandleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv,      // FIXME: Support PredefinedExpr, ObjCEncodeExpr, MakeStringConstant      RVal = APValue(Base, CharUnits::Zero(), APValue::NoLValuePath(), 0);    } else { -    Info.Diag(Conv->getExprLoc(), diag::note_invalid_subexpr_in_const_expr); +    Info.Diag(Conv, diag::note_invalid_subexpr_in_const_expr);      return false;    } @@ -1976,7 +1986,7 @@ static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E,    // Check this cast lands within the final derived-to-base subobject path.    if (D.MostDerivedPathLength + E->path_size() > D.Entries.size()) { -    Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_invalid_downcast) +    Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)        << D.MostDerivedType << TargetQT;      return false;    } @@ -1991,7 +2001,7 @@ static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E,    else      FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);    if (FinalType->getCanonicalDecl() != TargetType->getCanonicalDecl()) { -    Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_invalid_downcast) +    Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)        << D.MostDerivedType << TargetQT;      return false;    } @@ -2420,13 +2430,13 @@ protected:    typedef ExprEvaluatorBase ExprEvaluatorBaseTy;    OptionalDiagnostic CCEDiag(const Expr *E, diag::kind D) { -    return Info.CCEDiag(E->getExprLoc(), D); +    return Info.CCEDiag(E, D);    }    /// Report an evaluation error. This should only be called when an error is    /// first discovered. When propagating an error, just return false.    bool Error(const Expr *E, diag::kind D) { -    Info.Diag(E->getExprLoc(), D); +    Info.Diag(E, D);      return false;    }    bool Error(const Expr *E) { @@ -2957,7 +2967,7 @@ bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {      return Success(E);    CXXRecordDecl *RD = E->getExprOperand()->getType()->getAsCXXRecordDecl();    if (RD && RD->isPolymorphic()) { -    Info.Diag(E->getExprLoc(), diag::note_constexpr_typeid_polymorphic) +    Info.Diag(E, diag::note_constexpr_typeid_polymorphic)        << E->getExprOperand()->getType()        << E->getExprOperand()->getSourceRange();      return false; @@ -3405,7 +3415,7 @@ bool RecordExprEvaluator::ZeroInitialization(const Expr *E) {    }    if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) { -    Info.Diag(E->getExprLoc(), diag::note_constexpr_virtual_base) << RD; +    Info.Diag(E, diag::note_constexpr_virtual_base) << RD;      return false;    } @@ -4115,7 +4125,7 @@ static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info) {    if (!Val.isInt()) {      // FIXME: It would be better to produce the diagnostic for casting      //        a pointer to an integer. -    Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr); +    Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);      return false;    }    Result = Val.getInt(); @@ -4338,10 +4348,10 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {    case Builtin::BIstrlen:      // A call to strlen is not a constant expression.      if (Info.getLangOpts().CPlusPlus0x) -      Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_invalid_function) +      Info.CCEDiag(E, diag::note_constexpr_invalid_function)          << /*isConstexpr*/0 << /*isConstructor*/0 << "'strlen'";      else -      Info.CCEDiag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr); +      Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);      // Fall through.    case Builtin::BI__builtin_strlen:      // As an extension, we support strlen() and __builtin_strlen() as constant @@ -5981,17 +5991,17 @@ static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E) {      Result = Info.CurrentCall->Temporaries[E];    } else if (E->getType()->isVoidType()) {      if (Info.getLangOpts().CPlusPlus0x) -      Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_nonliteral) +      Info.CCEDiag(E, diag::note_constexpr_nonliteral)          << E->getType();      else -      Info.CCEDiag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr); +      Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);      if (!EvaluateVoid(E, Info))        return false;    } else if (Info.getLangOpts().CPlusPlus0x) { -    Info.Diag(E->getExprLoc(), diag::note_constexpr_nonliteral) << E->getType(); +    Info.Diag(E, diag::note_constexpr_nonliteral) << E->getType();      return false;    } else { -    Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr); +    Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);      return false;    }  | 

