diff --git a/lib/AST/Comment.cpp b/lib/AST/Comment.cpp index 89a7b7fa902e2de05d7aa1b02c237b86c9abb13c..307104224a635eadcc508a4a94537dc8fe3a22fb 100644 --- a/lib/AST/Comment.cpp +++ b/lib/AST/Comment.cpp @@ -113,6 +113,65 @@ bool ParagraphComment::isWhitespaceNoCache() const { return true; } +static TypeLoc lookThroughTypedefOrTypeAliasLocs(TypeLoc &SrcTL) { + TypeLoc TL = SrcTL.IgnoreParens(); + + // Look through qualified types. + if (QualifiedTypeLoc QualifiedTL = TL.getAs<QualifiedTypeLoc>()) + return QualifiedTL.getUnqualifiedLoc(); + // Look through pointer types. + if (PointerTypeLoc PointerTL = TL.getAs<PointerTypeLoc>()) + return PointerTL.getPointeeLoc().getUnqualifiedLoc(); + // Look through reference types. + if (ReferenceTypeLoc ReferenceTL = TL.getAs<ReferenceTypeLoc>()) + return ReferenceTL.getPointeeLoc().getUnqualifiedLoc(); + // Look through adjusted types. + if (AdjustedTypeLoc ATL = TL.getAs<AdjustedTypeLoc>()) + return ATL.getOriginalLoc(); + if (BlockPointerTypeLoc BlockPointerTL = TL.getAs<BlockPointerTypeLoc>()) + return BlockPointerTL.getPointeeLoc().getUnqualifiedLoc(); + if (MemberPointerTypeLoc MemberPointerTL = TL.getAs<MemberPointerTypeLoc>()) + return MemberPointerTL.getPointeeLoc().getUnqualifiedLoc(); + if (ElaboratedTypeLoc ETL = TL.getAs<ElaboratedTypeLoc>()) + return ETL.getNamedTypeLoc(); + + return TL; +} + +static bool getFunctionTypeLoc(TypeLoc TL, FunctionTypeLoc &ResFTL) { + TypeLoc PrevTL; + while (PrevTL != TL) { + PrevTL = TL; + TL = lookThroughTypedefOrTypeAliasLocs(TL); + } + + if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) { + ResFTL = FTL; + return true; + } + + if (TemplateSpecializationTypeLoc STL = + TL.getAs<TemplateSpecializationTypeLoc>()) { + // If we have a typedef to a template specialization with exactly one + // template argument of a function type, this looks like std::function, + // boost::function, or other function wrapper. Treat these typedefs as + // functions. + if (STL.getNumArgs() != 1) + return false; + TemplateArgumentLoc MaybeFunction = STL.getArgLoc(0); + if (MaybeFunction.getArgument().getKind() != TemplateArgument::Type) + return false; + TypeSourceInfo *MaybeFunctionTSI = MaybeFunction.getTypeSourceInfo(); + TypeLoc TL = MaybeFunctionTSI->getTypeLoc().getUnqualifiedLoc(); + if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) { + ResFTL = FTL; + return true; + } + } + + return false; +} + const char *ParamCommandComment::getDirectionAsString(PassDirection D) { switch (D) { case ParamCommandComment::In: @@ -238,70 +297,11 @@ void DeclInfo::fill() { if (!TSI) break; TypeLoc TL = TSI->getTypeLoc().getUnqualifiedLoc(); - while (true) { - TL = TL.IgnoreParens(); - // Look through qualified types. - if (QualifiedTypeLoc QualifiedTL = TL.getAs<QualifiedTypeLoc>()) { - TL = QualifiedTL.getUnqualifiedLoc(); - continue; - } - // Look through pointer types. - if (PointerTypeLoc PointerTL = TL.getAs<PointerTypeLoc>()) { - TL = PointerTL.getPointeeLoc().getUnqualifiedLoc(); - continue; - } - // Look through reference types. - if (ReferenceTypeLoc ReferenceTL = TL.getAs<ReferenceTypeLoc>()) { - TL = ReferenceTL.getPointeeLoc().getUnqualifiedLoc(); - continue; - } - // Look through adjusted types. - if (AdjustedTypeLoc ATL = TL.getAs<AdjustedTypeLoc>()) { - TL = ATL.getOriginalLoc(); - continue; - } - if (BlockPointerTypeLoc BlockPointerTL = - TL.getAs<BlockPointerTypeLoc>()) { - TL = BlockPointerTL.getPointeeLoc().getUnqualifiedLoc(); - continue; - } - if (MemberPointerTypeLoc MemberPointerTL = - TL.getAs<MemberPointerTypeLoc>()) { - TL = MemberPointerTL.getPointeeLoc().getUnqualifiedLoc(); - continue; - } - if (ElaboratedTypeLoc ETL = TL.getAs<ElaboratedTypeLoc>()) { - TL = ETL.getNamedTypeLoc(); - continue; - } - // Is this a typedef for a function type? - if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) { - Kind = FunctionKind; - ParamVars = FTL.getParams(); - ReturnType = FTL.getReturnLoc().getType(); - break; - } - if (TemplateSpecializationTypeLoc STL = - TL.getAs<TemplateSpecializationTypeLoc>()) { - // If we have a typedef to a template specialization with exactly one - // template argument of a function type, this looks like std::function, - // boost::function, or other function wrapper. Treat these typedefs as - // functions. - if (STL.getNumArgs() != 1) - break; - TemplateArgumentLoc MaybeFunction = STL.getArgLoc(0); - if (MaybeFunction.getArgument().getKind() != TemplateArgument::Type) - break; - TypeSourceInfo *MaybeFunctionTSI = MaybeFunction.getTypeSourceInfo(); - TypeLoc TL = MaybeFunctionTSI->getTypeLoc().getUnqualifiedLoc(); - if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) { - Kind = FunctionKind; - ParamVars = FTL.getParams(); - ReturnType = FTL.getReturnLoc().getType(); - } - break; - } - break; + FunctionTypeLoc FTL; + if (getFunctionTypeLoc(TL, FTL)) { + Kind = FunctionKind; + ParamVars = FTL.getParams(); + ReturnType = FTL.getReturnLoc().getType(); } break; }