diff options
author | David Blaikie <dblaikie@gmail.com> | 2013-02-18 22:06:02 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2013-02-18 22:06:02 +0000 |
commit | 39e6ab4be93d9c5e729a578ddd9d415cd2d49872 (patch) | |
tree | fc9c9aad9c0b7b392ff2b08bb1d5df59c8d6c048 | |
parent | 9ba7627d25a7555b1afff04f685d2f161974e682 (diff) |
Replace TypeLoc llvm::cast support to be well-defined.
The TypeLoc hierarchy used the llvm::cast machinery to perform undefined
behavior by casting pointers/references to TypeLoc objects to derived types
and then using the derived copy constructors (or even returning pointers to
derived types that actually point to the original TypeLoc object).
Some context is in this thread:
http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-December/056804.html
Though it's spread over a few months which can be hard to read in the mail
archive.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175462 91177308-0d34-0410-b5e6-96231b3b80d8
29 files changed, 245 insertions, 221 deletions
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index cc622783a5..faec5ebe09 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -594,7 +594,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) { #define ABSTRACT_TYPELOC(CLASS, BASE) #define TYPELOC(CLASS, BASE) \ case TypeLoc::CLASS: \ - return getDerived().Traverse##CLASS##TypeLoc(*cast<CLASS##TypeLoc>(&TL)); + return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>()); #include "clang/AST/TypeLocNodes.def" } @@ -2100,8 +2100,7 @@ bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) { if (S->hasExplicitParameters() && S->hasExplicitResultType()) { // Visit the whole type. TRY_TO(TraverseTypeLoc(TL)); - } else if (isa<FunctionProtoTypeLoc>(TL)) { - FunctionProtoTypeLoc Proto = cast<FunctionProtoTypeLoc>(TL); + } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) { if (S->hasExplicitParameters()) { // Visit parameters. for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I) { diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index 20584c8106..d58b79af01 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -44,6 +44,28 @@ protected: void *Data; public: + template<typename T> + T castAs() const { + assert(T::isType(this)); + T t; + TypeLoc& tl = t; + tl = *this; + return t; + } + template<typename T> + T getAs() const { + if (!T::isType(this)) + return T(); + T t; + TypeLoc& tl = t; + tl = *this; + return t; + } + + static bool isType(const TypeLoc*) { + return true; + } + /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum, /// except it also defines a Qualified enum that corresponds to the /// QualifiedLoc class. @@ -119,11 +141,7 @@ public: /// \brief Skips past any qualifiers, if this is qualified. UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header - TypeLoc IgnoreParens() const { - if (isa<ParenTypeLoc>(this)) - return IgnoreParensImpl(*this); - return *this; - } + TypeLoc IgnoreParens() const; /// \brief Initializes this to state that every location in this /// type is the given location. @@ -187,7 +205,9 @@ public: return (TypeLocClass) getTypePtr()->getTypeClass(); } - static bool classof(const TypeLoc *TL) { +private: + friend class TypeLoc; + static bool isType(const TypeLoc *TL) { return !TL->getType().hasLocalQualifiers(); } }; @@ -231,15 +251,17 @@ public: getFullDataSizeForType(getType().getLocalUnqualifiedType()); } - static bool classof(const TypeLoc *TL) { +private: + friend class TypeLoc; + static bool isType(const TypeLoc *TL) { return TL->getType().hasLocalQualifiers(); } }; inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const { - if (isa<QualifiedTypeLoc>(this)) - return cast<QualifiedTypeLoc>(this)->getUnqualifiedLoc(); - return cast<UnqualTypeLoc>(*this); + if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>()) + return Loc.getUnqualifiedLoc(); + return castAs<UnqualTypeLoc>(); } /// A metaprogramming base class for TypeLoc classes which correspond @@ -280,24 +302,22 @@ class ConcreteTypeLoc : public Base { return static_cast<const Derived*>(this); } -public: - unsigned getLocalDataSize() const { - return sizeof(LocalData) + asDerived()->getExtraLocalDataSize(); - } - // Give a default implementation that's useful for leaf types. - unsigned getFullDataSize() const { - return asDerived()->getLocalDataSize() + getInnerTypeSize(); + friend class TypeLoc; + static bool isType(const TypeLoc *TL) { + return Derived::classofType(TL->getTypePtr()); } static bool classofType(const Type *Ty) { return TypeClass::classof(Ty); } - static bool classof(const TypeLoc *TL) { - return Derived::classofType(TL->getTypePtr()); +public: + unsigned getLocalDataSize() const { + return sizeof(LocalData) + asDerived()->getExtraLocalDataSize(); } - static bool classof(const UnqualTypeLoc *TL) { - return Derived::classofType(TL->getTypePtr()); + // Give a default implementation that's useful for leaf types. + unsigned getFullDataSize() const { + return asDerived()->getLocalDataSize() + getInnerTypeSize(); } TypeLoc getNextTypeLoc() const { @@ -362,18 +382,19 @@ private: /// information. See the note on ConcreteTypeLoc. template <class Base, class Derived, class TypeClass> class InheritingConcreteTypeLoc : public Base { -public: + friend class TypeLoc; static bool classofType(const Type *Ty) { return TypeClass::classof(Ty); } - static bool classof(const TypeLoc *TL) { + static bool isType(const TypeLoc *TL) { return Derived::classofType(TL->getTypePtr()); } - static bool classof(const UnqualTypeLoc *TL) { + static bool isType(const UnqualTypeLoc *TL) { return Derived::classofType(TL->getTypePtr()); } +public: const TypeClass *getTypePtr() const { return cast<TypeClass>(Base::getTypePtr()); } @@ -406,7 +427,9 @@ public: setNameLoc(Loc); } - static bool classof(const TypeLoc *TL); +private: + friend class TypeLoc; + static bool isType(const TypeLoc *TL); }; @@ -899,6 +922,11 @@ public: } }; +inline TypeLoc TypeLoc::IgnoreParens() const { + if (ParenTypeLoc::isType(this)) + return IgnoreParensImpl(*this); + return *this; +} struct PointerLikeLocInfo { SourceLocation StarLoc; diff --git a/include/clang/AST/TypeLocVisitor.h b/include/clang/AST/TypeLocVisitor.h index 50fc43913f..db5775aa14 100644 --- a/include/clang/AST/TypeLocVisitor.h +++ b/include/clang/AST/TypeLocVisitor.h @@ -21,7 +21,7 @@ namespace clang { #define DISPATCH(CLASSNAME) \ return static_cast<ImplClass*>(this)-> \ - Visit##CLASSNAME(cast<CLASSNAME>(TyLoc)) + Visit##CLASSNAME(TyLoc.castAs<CLASSNAME>()) template<typename ImplClass, typename RetTy=void> class TypeLocVisitor { diff --git a/lib/ARCMigrate/TransGCAttrs.cpp b/lib/ARCMigrate/TransGCAttrs.cpp index eec7306ba7..d8be1ae746 100644 --- a/lib/ARCMigrate/TransGCAttrs.cpp +++ b/lib/ARCMigrate/TransGCAttrs.cpp @@ -63,19 +63,18 @@ public: return; TypeLoc TL = TInfo->getTypeLoc(); while (TL) { - if (const QualifiedTypeLoc *QL = dyn_cast<QualifiedTypeLoc>(&TL)) { - TL = QL->getUnqualifiedLoc(); - } else if (const AttributedTypeLoc * - Attr = dyn_cast<AttributedTypeLoc>(&TL)) { - if (handleAttr(*Attr, D)) + if (QualifiedTypeLoc QL = TL.getAs<QualifiedTypeLoc>()) { + TL = QL.getUnqualifiedLoc(); + } else if (AttributedTypeLoc Attr = TL.getAs<AttributedTypeLoc>()) { + if (handleAttr(Attr, D)) break; - TL = Attr->getModifiedLoc(); - } else if (const ArrayTypeLoc *Arr = dyn_cast<ArrayTypeLoc>(&TL)) { - TL = Arr->getElementLoc(); - } else if (const PointerTypeLoc *PT = dyn_cast<PointerTypeLoc>(&TL)) { - TL = PT->getPointeeLoc(); - } else if (const ReferenceTypeLoc *RT = dyn_cast<ReferenceTypeLoc>(&TL)) - TL = RT->getPointeeLoc(); + TL = Attr.getModifiedLoc(); + } else if (ArrayTypeLoc Arr = TL.getAs<ArrayTypeLoc>()) { + TL = Arr.getElementLoc(); + } else if (PointerTypeLoc PT = TL.getAs<PointerTypeLoc>()) { + TL = PT.getPointeeLoc(); + } else if (ReferenceTypeLoc RT = TL.getAs<ReferenceTypeLoc>()) + TL = RT.getPointeeLoc(); else break; } @@ -249,8 +248,9 @@ static void checkAllAtProps(MigrationContext &MigrateCtx, if (!TInfo) return; TypeLoc TL = TInfo->getTypeLoc(); - if (AttributedTypeLoc *ATL = dyn_cast<AttributedTypeLoc>(&TL)) { - ATLs.push_back(std::make_pair(*ATL, PD)); + if (AttributedTypeLoc ATL = + TL.getAs<AttributedTypeLoc>()) { + ATLs.push_back(std::make_pair(ATL, PD)); if (TInfo->getType().getObjCLifetime() == Qualifiers::OCL_Weak) { hasWeak = true; } else if (TInfo->getType().getObjCLifetime() == Qualifiers::OCL_Strong) diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 62fd9da1b4..952162e909 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2957,8 +2957,8 @@ ASTContext::getTemplateSpecializationTypeInfo(TemplateName Name, QualType TST = getTemplateSpecializationType(Name, Args, Underlying); TypeSourceInfo *DI = CreateTypeSourceInfo(TST); - TemplateSpecializationTypeLoc TL - = cast<TemplateSpecializationTypeLoc>(DI->getTypeLoc()); + TemplateSpecializationTypeLoc TL = + DI->getTypeLoc().castAs<TemplateSpecializationTypeLoc>(); TL.setTemplateKeywordLoc(SourceLocation()); TL.setTemplateNameLoc(NameLoc); TL.setLAngleLoc(Args.getLAngleLoc()); diff --git a/lib/AST/Comment.cpp b/lib/AST/Comment.cpp index ea1a3f737a..db55c04544 100644 --- a/lib/AST/Comment.cpp +++ b/lib/AST/Comment.cpp @@ -241,32 +241,32 @@ void DeclInfo::fill() { while (true) { TL = TL.IgnoreParens(); // Look through qualified types. - if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) { - TL = QualifiedTL->getUnqualifiedLoc(); + if (QualifiedTypeLoc QualifiedTL = TL.getAs<QualifiedTypeLoc>()) { + TL = QualifiedTL.getUnqualifiedLoc(); continue; } // Look through pointer types. - if (PointerTypeLoc *PointerTL = dyn_cast<PointerTypeLoc>(&TL)) { - TL = PointerTL->getPointeeLoc().getUnqualifiedLoc(); + if (PointerTypeLoc PointerTL = TL.getAs<PointerTypeLoc>()) { + TL = PointerTL.getPointeeLoc().getUnqualifiedLoc(); continue; } - if (BlockPointerTypeLoc *BlockPointerTL = - dyn_cast<BlockPointerTypeLoc>(&TL)) { - TL = BlockPointerTL->getPointeeLoc().getUnqualifiedLoc(); + if (BlockPointerTypeLoc BlockPointerTL = + TL.getAs<BlockPointerTypeLoc>()) { + TL = BlockPointerTL.getPointeeLoc().getUnqualifiedLoc(); continue; } - if (MemberPointerTypeLoc *MemberPointerTL = - dyn_cast<MemberPointerTypeLoc>(&TL)) { - TL = MemberPointerTL->getPointeeLoc().getUnqualifiedLoc(); + if (MemberPointerTypeLoc MemberPointerTL = + TL.getAs<MemberPointerTypeLoc>()) { + TL = MemberPointerTL.getPointeeLoc().getUnqualifiedLoc(); continue; } // Is this a typedef for a function type? - if (FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL)) { + if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) { Kind = FunctionKind; - ArrayRef<ParmVarDecl *> Params = FTL->getParams(); + ArrayRef<ParmVarDecl *> Params = FTL.getParams(); ParamVars = ArrayRef<const ParmVarDecl *>(Params.data(), Params.size()); - ResultType = FTL->getResultLoc().getType(); + ResultType = FTL.getResultLoc().getType(); break; } break; diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index baa16b04ea..b0fc25cfa4 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -396,7 +396,7 @@ isTemplate(const NamedDecl *ND, TypeSourceInfo *TSI = Spec->getTypeAsWritten(); if (TSI) { TemplateSpecializationTypeLoc TSTL = - cast<TemplateSpecializationTypeLoc>(TSI->getTypeLoc()); + TSI->getTypeLoc().castAs<TemplateSpecializationTypeLoc>(); TemplateArgumentListInfo LI(TSTL.getLAngleLoc(), TSTL.getRAngleLoc()); for (unsigned i = 0, e = TSTL.getNumArgs(); i != e; ++i) TemplateArgs.push_back(TSTL.getArgLoc(i)); diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp index 6519340c87..f1b5e4b0b8 100644 --- a/lib/AST/TemplateBase.cpp +++ b/lib/AST/TemplateBase.cpp @@ -466,8 +466,8 @@ TemplateArgumentLoc::getPackExpansionPattern(SourceLocation &Ellipsis, ExpansionTSInfo = Context.getTrivialTypeSourceInfo( getArgument().getAsType(), Ellipsis); - PackExpansionTypeLoc Expansion - = cast<PackExpansionTypeLoc>(ExpansionTSInfo->getTypeLoc()); + PackExpansionTypeLoc Expansion = + ExpansionTSInfo->getTypeLoc().castAs<PackExpansionTypeLoc>(); Ellipsis = Expansion.getEllipsisLoc(); TypeLoc Pattern = Expansion.getPatternLoc(); diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp index 010ea2d9a8..fe66714e4d 100644 --- a/lib/AST/TypeLoc.cpp +++ b/lib/AST/TypeLoc.cpp @@ -86,7 +86,7 @@ void TypeLoc::initializeImpl(ASTContext &Context, TypeLoc TL, #define ABSTRACT_TYPELOC(CLASS, PARENT) #define TYPELOC(CLASS, PARENT) \ case CLASS: { \ - CLASS##TypeLoc TLCasted = cast<CLASS##TypeLoc>(TL); \ + CLASS##TypeLoc TLCasted = TL.castAs<CLASS##TypeLoc>(); \ TLCasted.initializeLocal(Context, Loc); \ TL = TLCasted.getNextTypeLoc(); \ if (!TL) return; \ @@ -106,7 +106,8 @@ SourceLocation TypeLoc::getBeginLoc() const { LeftMost = Cur; break; case FunctionProto: - if (cast<FunctionProtoTypeLoc>(&Cur)->getTypePtr()->hasTrailingReturn()) { + if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr() + ->hasTrailingReturn()) { LeftMost = Cur; break; } @@ -151,7 +152,7 @@ SourceLocation TypeLoc::getEndLoc() const { Last = Cur; break; case FunctionProto: - if (cast<FunctionProtoTypeLoc>(&Cur)->getTypePtr()->hasTrailingReturn()) + if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()->hasTrailingReturn()) Last = TypeLoc(); else Last = Cur; @@ -198,7 +199,7 @@ namespace { /// because it's a convenient base class. Ideally we would not accept /// those here, but ideally we would have better implementations for /// them. -bool TypeSpecTypeLoc::classof(const TypeLoc *TL) { +bool TypeSpecTypeLoc::isType(const TypeLoc *TL) { if (TL->getType().hasLocalQualifiers()) return false; return TSTChecker().Visit(*TL); } @@ -278,8 +279,8 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const { } TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) { - while (ParenTypeLoc* PTL = dyn_cast<ParenTypeLoc>(&TL)) - TL = PTL->getInnerLoc(); + while (ParenTypeLoc PTL = TL.getAs<ParenTypeLoc>()) + TL = PTL.getInnerLoc(); return TL; } diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index d76592438b..f3a290cb8d 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -5772,14 +5772,13 @@ static bool IsTailPaddedMemberArray(Sema &S, llvm::APInt Size, while (TInfo) { TypeLoc TL = TInfo->getTypeLoc(); // Look through typedefs. - const TypedefTypeLoc *TTL = dyn_cast<TypedefTypeLoc>(&TL); - if (TTL) { - const TypedefNameDecl *TDL = TTL->getTypedefNameDecl(); + if (TypedefTypeLoc TTL = TL.getAs<TypedefTypeLoc>()) { + const TypedefNameDecl *TDL = TTL.getTypedefNameDecl(); TInfo = TDL->getTypeSourceInfo(); continue; } - if (const ConstantArrayTypeLoc *CTL = dyn_cast<ConstantArrayTypeLoc>(&TL)) { - const Expr *SizeExpr = dyn_cast<IntegerLiteral>(CTL->getSizeExpr()); + if (ConstantArrayTypeLoc CTL = TL.getAs<ConstantArrayTypeLoc>()) { + const Expr *SizeExpr = dyn_cast<IntegerLiteral>(CTL.getSizeExpr()); if (!SizeExpr || SizeExpr->getExprLoc().isMacroID()) return false; } diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index e145d3ff66..f894a0ba27 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -2147,36 +2147,35 @@ static std::string FormatFunctionParameter(ASTContext &Context, // The argument for a block pointer parameter is a block literal with // the appropriate type. - FunctionTypeLoc *Block = 0; - FunctionProtoTypeLoc *BlockProto = 0; + FunctionTypeLoc Block; + FunctionProtoTypeLoc BlockProto; TypeLoc TL; if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) { TL = TSInfo->getTypeLoc().getUnqualifiedLoc(); while (true) { // Look through typedefs. if (!SuppressBlock) { - if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) { - if (TypeSourceInfo *InnerTSInfo - = TypedefTL->getTypedefNameDecl()->getTypeSourceInfo()) { + if (TypedefTypeLoc TypedefTL = TL.getAs<TypedefTypeLoc>()) { + if (TypeSourceInfo *InnerTSInfo = + TypedefTL.getTypedefNameDecl()->getTypeSourceInfo()) { TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc(); continue; } } // Look through qualified types - if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) { - TL = QualifiedTL->getUnqualifiedLoc(); + if (QualifiedTypeLoc QualifiedTL = TL.getAs<QualifiedTypeLoc>()) { + TL = QualifiedTL.getUnqualifiedLoc(); continue; } } // Try to get the function prototype behind the block pointer type, // then we're done. - if (BlockPointerTypeLoc *BlockPtr - = dyn_cast<BlockPointerTypeLoc>(&TL)) { - TL = BlockPtr->getPointeeLoc().IgnoreParens(); - Block = dyn_cast<FunctionTypeLoc>(&TL); - BlockProto = dyn_cast<FunctionProtoTypeLoc>(&TL); + if (BlockPointerTypeLoc BlockPtr = TL.getAs<BlockPointerTypeLoc>()) { + TL = BlockPtr.getPointeeLoc().IgnoreParens(); + Block = TL.getAs<FunctionTypeLoc>(); + BlockProto = TL.getAs<FunctionProtoTypeLoc>(); } break; } @@ -2204,27 +2203,27 @@ static std::string FormatFunctionParameter(ASTContext &Context, // We have the function prototype behind the block pointer type, as it was // written in the source. std::string Result; - QualType ResultType = Block->getTypePtr()->getResultType(); + QualType ResultType = Block.getTypePtr()->getResultType(); if (!ResultType->isVoidType() || SuppressBlock) ResultType.getAsStringInternal(Result, Policy); // Format the parameter list. std::string Params; - if (!BlockProto || Block->getNumArgs() == 0) { - if (BlockProto && BlockProto->getTypePtr()->isVariadic()) + if (!BlockProto || Block.getNumArgs() == 0) { + if (BlockProto && BlockProto.getTypePtr()->isVariadic()) Params = "(...)"; else Params = "(void)"; } else { Params += "("; - for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) { + for (unsigned I = 0, N = Block.getNumArgs(); I != N; ++I) { if (I) Params += ", "; - Params += FormatFunctionParameter(Context, Policy, Block->getArg(I), + Params += FormatFunctionParameter(Context, Policy, Block.getArg(I), /*SuppressName=*/false, /*SuppressBlock=*/true); - if (I == N - 1 && BlockProto->getTypePtr()->isVariadic()) + if (I == N - 1 && BlockProto.getTypePtr()->isVariadic()) Params += ", ..."; } Params += ")"; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index d425902699..7667681c79 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -4066,29 +4066,29 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T, static void FixInvalidVariablyModifiedTypeLoc(TypeLoc SrcTL, TypeLoc DstTL) { - if (PointerTypeLoc* SrcPTL = dyn_cast<PointerTypeLoc>(&SrcTL)) { - PointerTypeLoc* DstPTL = cast<PointerTypeLoc>(&DstTL); - FixInvalidVariablyModifiedTypeLoc(SrcPTL->getPointeeLoc(), - DstPTL->getPointeeLoc()); - DstPTL->setStarLoc(SrcPTL->getStarLoc()); + if (PointerTypeLoc SrcPTL = SrcTL.getAs<PointerTypeLoc>()) { + PointerTypeLoc DstPTL = DstTL.castAs<PointerTypeLoc>(); + FixInvalidVariablyModifiedTypeLoc(SrcPTL.getPointeeLoc(), + DstPTL.getPointeeLoc()); + DstPTL.setStarLoc(SrcPTL.getStarLoc()); return; } - if (ParenTypeLoc* SrcPTL = dyn_cast<ParenTypeLoc>(&SrcTL)) { - ParenTypeLoc* DstPTL = cast<ParenTypeLoc>(&DstTL); - FixInvalidVariablyModifiedTypeLoc(SrcPTL->getInnerLoc(), - DstPTL->getInnerLoc()); - DstPTL->setLParenLoc(SrcPTL->getLParenLoc()); - DstPTL->setRParenLoc(SrcPTL->getRParenLoc()); + if (ParenTypeLoc SrcPTL = SrcTL.getAs<ParenTypeLoc>()) { + ParenTypeLoc DstPTL = DstTL.castAs<ParenTypeLoc>(); + FixInvalidVariablyModifiedTypeLoc(SrcPTL.getInnerLoc(), + DstPTL.getInnerLoc()); + DstPTL.setLParenLoc(SrcPTL.getLParenLoc()); + DstPTL.setRParenLoc(SrcPTL.getRParenLoc()); return; } - ArrayTypeLoc* SrcATL = cast<ArrayTypeLoc>(&SrcTL); - ArrayTypeLoc* DstATL = cast<ArrayTypeLoc>(&DstTL); - TypeLoc SrcElemTL = SrcATL->getElementLoc(); - TypeLoc DstElemTL = DstATL->getElementLoc(); + ArrayTypeLoc SrcATL = SrcTL.castAs<ArrayTypeLoc>(); + ArrayTypeLoc DstATL = DstTL.castAs<ArrayTypeLoc>(); + TypeLoc SrcElemTL = SrcATL.getElementLoc(); + TypeLoc DstElemTL = DstATL.getElementLoc(); DstElemTL.initializeFullCopy(SrcElemTL); - DstATL->setLBracketLoc(SrcATL->getLBracketLoc()); - DstATL->setSizeExpr(SrcATL->getSizeExpr()); - DstATL->setRBracketLoc(SrcATL->getRBracketLoc()); + DstATL.setLBracketLoc(SrcATL.getLBracketLoc()); + DstATL.setSizeExpr(SrcATL.getSizeExpr()); + DstATL.setRBracketLoc(SrcATL.getRBracketLoc()); } /// Helper method to turn variable array types into constant array @@ -6600,12 +6600,12 @@ static SourceRange getResultSourceRange(const FunctionDecl *FD) { return SourceRange(); TypeLoc TL = TSI->getTypeLoc(); - FunctionTypeLoc *FunctionTL = dyn_cast<FunctionTypeLoc>(&TL); + FunctionTypeLoc FunctionTL = TL.getAs<FunctionTypeLoc>(); if (!FunctionTL) return SourceRange(); - TypeLoc ResultTL = FunctionTL->getResultLoc(); - if (isa<BuiltinTypeLoc>(ResultTL.getUnqualifiedLoc())) + TypeLoc ResultTL = FunctionTL.getResultLoc(); + if (ResultTL.getUnqualifiedLoc().getAs<BuiltinTypeLoc>()) return ResultTL.getSourceRange(); return SourceRange(); @@ -8291,11 +8291,11 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { // but that could be a zero-parameter prototype TypeSourceInfo* TI = PossibleZeroParamPrototype->getTypeSourceInfo(); TypeLoc TL = TI->getTypeLoc(); - if (FunctionNoProtoTypeLoc* FTL = dyn_cast<FunctionNoProtoTypeLoc>(&TL)) + if (FunctionNoProtoTypeLoc FTL = TL.getAs<FunctionNoProtoTypeLoc>()) Diag(PossibleZeroParamPrototype->getLocation(), diag::note_declaration_not_a_prototype) << PossibleZeroParamPrototype - << FixItHint::CreateInsertion(FTL->getRParenLoc(), "void"); + << FixItHint::CreateInsertion(FTL.getRParenLoc(), "void"); } } diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 97d1ea2cf1..2f3634a278 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -3715,10 +3715,10 @@ static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) { FunctionDecl *FD = cast<FunctionDecl>(D); if (!FD->getResultType()->isVoidType()) { TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens(); - if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) { + if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) { S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) << FD->getType() - << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(), + << FixItHint::CreateReplacement(FTL.getResultLoc().getSourceRange(), "void"); } else { S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 763a4ce774..1711c8726e 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -3757,7 +3757,7 @@ struct CheckAbstractUsage { switch (TL.getTypeLocClass()) { #define ABSTRACT_TYPELOC(CLASS, PARENT) #define TYPELOC(CLASS, PARENT) \ - case TypeLoc::CLASS: Check(cast<CLASS##TypeLoc>(TL), Sel); break; + case TypeLoc::CLASS: Check(TL.castAs<CLASS##TypeLoc>(), Sel); break; #include "clang/AST/TypeLocNodes.def" } } @@ -10432,15 +10432,16 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T); if (isa<DependentNameType>(T)) { - DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc()); + DependentNameTypeLoc TL = + TSI->getTypeLoc().castAs<DependentNameTypeLoc>(); TL.setElaboratedKeywordLoc(TagLoc); TL.setQualifierLoc(QualifierLoc); TL.setNameLoc(NameLoc); } else { - ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc()); + ElaboratedTypeLoc TL = TSI->getTypeLoc().castAs<ElaboratedTypeLoc>(); TL.setElaboratedKeywordLoc(TagLoc); TL.setQualifierLoc(QualifierLoc); - cast<TypeSpecTypeLoc>(TL.getNamedTypeLoc()).setNameLoc(NameLoc); + TL.getNamedTypeLoc().castAs<TypeSpecTypeLoc>().setNameLoc(NameLoc); } FriendDecl *Friend = FriendDecl::Create(Context, CurContext, NameLoc, @@ -10460,7 +10461,7 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, ElaboratedTypeKeyword ETK = TypeWithKeyword::getKeywordForTagTypeKind(Kind); QualType T = Context.getDependentNameType(ETK, SS.getScopeRep(), Name); TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T); - DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc()); + DependentNameTypeLoc TL = TSI->getTypeLoc().castAs<DependentNameTypeLoc>(); TL.setElaboratedKeywordLoc(TagLoc); TL.setQualifierLoc(SS.getWithLocInContext(Context)); TL.setNameLoc(NameLoc); @@ -11538,7 +11539,7 @@ bool Sema::checkThisInStaticMemberFunctionType(CXXMethodDecl *Method) { return false; TypeLoc TL = TSInfo->getTypeLoc(); - FunctionProtoTypeLoc *ProtoTL = dyn_cast<FunctionProtoTypeLoc>(&TL); + FunctionProtoTypeLoc ProtoTL = TL.getAs<FunctionProtoTypeLoc>(); if (!ProtoTL) return false; @@ -11549,12 +11550,12 @@ bool Sema::checkThisInStaticMemberFunctionType(CXXMethodDecl *Method) { // within a static member function as they are within a non-static member // function). [ Note: this is because declaration matching does not occur // until the complete declarator is known. - end note ] - const FunctionProtoType *Proto = ProtoTL->getTypePtr(); + const FunctionProtoType *Proto = ProtoTL.getTypePtr(); FindCXXThisExpr Finder(*this); // If the return type came after the cv-qualifier-seq, check it now. if (Proto->hasTrailingReturn() && - !Finder.TraverseTypeLoc(ProtoTL->getResultLoc())) + !Finder.TraverseTypeLoc(ProtoTL.getResultLoc())) return true; // Check the exception specification. @@ -11570,11 +11571,11 @@ bool Sema::checkThisInStaticMemberFunctionExceptionSpec(CXXMethodDecl *Method) { return false; TypeLoc TL = TSInfo->getTypeLoc(); - FunctionProtoTypeLoc *ProtoTL = dyn_cast<FunctionProtoTypeLoc>(&TL); + FunctionProtoTypeLoc ProtoTL = TL.getAs<FunctionProtoTypeLoc> |