From 38bc0060e60fef5395c23b8b75163e5bdee23af6 Mon Sep 17 00:00:00 2001 From: Eduardo Caldas Date: Thu, 27 Aug 2020 15:37:04 +0000 Subject: [PATCH] [SyntaxTree][NFC] Refactor function templates into functions taking base class The refactored functions were * `isReponsibleForCreatingDeclaration` * `getQualifiedNameStart` Differential Revision: https://reviews.llvm.org/D86719 --- clang/lib/Tooling/Syntax/BuildTree.cpp | 99 +++++++++++++++++----------------- 1 file changed, 51 insertions(+), 48 deletions(-) diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp index b07e9c3..2e9e744 100644 --- a/clang/lib/Tooling/Syntax/BuildTree.cpp +++ b/clang/lib/Tooling/Syntax/BuildTree.cpp @@ -197,18 +197,57 @@ static syntax::NodeKind getOperatorNodeKind(const CXXOperatorCallExpr &E) { llvm_unreachable("Unknown OverloadedOperatorKind enum"); } +/// Get the start of the qualified name. In the examples below it gives the +/// location of the `^`: +/// `int ^a;` +/// `int ^a::S::f(){}` +static SourceLocation getQualifiedNameStart(NamedDecl *D) { + assert((isa(D)) && + "only DeclaratorDecl and TypedefNameDecl are supported."); + + auto DN = D->getDeclName(); + bool IsAnonymous = DN.isIdentifier() && !DN.getAsIdentifierInfo(); + if (IsAnonymous) + return SourceLocation(); + + if (const auto *DD = dyn_cast(D)) { + if (DD->getQualifierLoc()) { + return DD->getQualifierLoc().getBeginLoc(); + } + } + + return D->getLocation(); +} + +/// Gets the range of the initializer inside an init-declarator C++ [dcl.decl]. +/// `int a;` -> range of ``, +/// `int *a = nullptr` -> range of `= nullptr`. +/// `int a{}` -> range of `{}`. +/// `int a()` -> range of `()`. +static SourceRange getInitializerRange(Decl *D) { + if (auto *V = dyn_cast(D)) { + auto *I = V->getInit(); + // Initializers in range-based-for are not part of the declarator + if (I && !V->isCXXForRangeDecl()) + return I->getSourceRange(); + } + + return SourceRange(); +} + /// Gets the range of declarator as defined by the C++ grammar. E.g. /// `int a;` -> range of `a`, /// `int *a;` -> range of `*a`, /// `int a[10];` -> range of `a[10]`, /// `int a[1][2][3];` -> range of `a[1][2][3]`, /// `int *a = nullptr` -> range of `*a = nullptr`. -/// FIMXE: \p Name must be a source range, e.g. for `operator+`. +/// `int S::f(){}` -> range of `S::f()`. +/// FIXME: \p Name must be a source range, e.g. for `operator+`. static SourceRange getDeclaratorRange(const SourceManager &SM, TypeLoc T, SourceLocation Name, SourceRange Initializer) { SourceLocation Start = GetStartLoc().Visit(T); - SourceLocation End = T.getSourceRange().getEnd(); + SourceLocation End = T.getEndLoc(); assert(End.isValid()); if (Name.isValid()) { if (Start.isInvalid()) @@ -378,11 +417,9 @@ public: /// Returns true if \p D is the last declarator in a chain and is thus /// reponsible for creating SimpleDeclaration for the whole chain. - template - bool isResponsibleForCreatingDeclaration(const T *D) const { - static_assert((std::is_base_of::value || - std::is_base_of::value), - "only DeclaratorDecl and TypedefNameDecl are supported."); + bool isResponsibleForCreatingDeclaration(const Decl *D) const { + assert((isa(D)) && + "only DeclaratorDecl and TypedefNameDecl are supported."); const Decl *Next = D->getNextDeclInContext(); @@ -390,15 +427,14 @@ public: if (Next == nullptr) { return true; } - const auto *NextT = dyn_cast(Next); // Next sibling is not the same type, this one is responsible. - if (NextT == nullptr) { + if (D->getKind() != Next->getKind()) { return true; } // Next sibling doesn't begin at the same loc, it must be a different // declaration, so this declarator is responsible. - if (NextT->getBeginLoc() != D->getBeginLoc()) { + if (Next->getBeginLoc() != D->getBeginLoc()) { return true; } @@ -1405,43 +1441,12 @@ public: } private: - template SourceLocation getQualifiedNameStart(T *D) { - static_assert((std::is_base_of::value || - std::is_base_of::value), - "only DeclaratorDecl and TypedefNameDecl are supported."); - - auto DN = D->getDeclName(); - bool IsAnonymous = DN.isIdentifier() && !DN.getAsIdentifierInfo(); - if (IsAnonymous) - return SourceLocation(); - - if (const auto *DD = dyn_cast(D)) { - if (DD->getQualifierLoc()) { - return DD->getQualifierLoc().getBeginLoc(); - } - } - - return D->getLocation(); - } - - SourceRange getInitializerRange(Decl *D) { - if (auto *V = dyn_cast(D)) { - auto *I = V->getInit(); - // Initializers in range-based-for are not part of the declarator - if (I && !V->isCXXForRangeDecl()) - return I->getSourceRange(); - } - - return SourceRange(); - } - /// Folds SimpleDeclarator node (if present) and in case this is the last /// declarator in the chain it also folds SimpleDeclaration node. template bool processDeclaratorAndDeclaration(T *D) { - SourceRange Initializer = getInitializerRange(D); - auto Range = getDeclaratorRange(Builder.sourceManager(), - D->getTypeSourceInfo()->getTypeLoc(), - getQualifiedNameStart(D), Initializer); + auto Range = getDeclaratorRange( + Builder.sourceManager(), D->getTypeSourceInfo()->getTypeLoc(), + getQualifiedNameStart(D), getInitializerRange(D)); // There doesn't have to be a declarator (e.g. `void foo(int)` only has // declaration, but no declarator). @@ -1464,10 +1469,8 @@ private: auto ReturnedType = L.getReturnLoc(); // Build node for the declarator, if any. - auto ReturnDeclaratorRange = - getDeclaratorRange(this->Builder.sourceManager(), ReturnedType, - /*Name=*/SourceLocation(), - /*Initializer=*/SourceLocation()); + auto ReturnDeclaratorRange = SourceRange(GetStartLoc().Visit(ReturnedType), + ReturnedType.getEndLoc()); syntax::SimpleDeclarator *ReturnDeclarator = nullptr; if (ReturnDeclaratorRange.isValid()) { ReturnDeclarator = new (allocator()) syntax::SimpleDeclarator; -- 2.7.4