njames93 created this revision. njames93 added a reviewer: sammccall. Herald added subscribers: usaxena95, kadircet, arphaman. njames93 requested review of this revision. Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov. Herald added a project: clang.
FindTarget on the virtual keyword or access specifier of a base specifier will now resolve to type of the base specifier. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D95338 Files: clang-tools-extra/clangd/FindTarget.cpp clang-tools-extra/clangd/unittests/FindTargetTests.cpp
Index: clang-tools-extra/clangd/unittests/FindTargetTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -230,6 +230,24 @@ {"void waldo()"}); } +TEST_F(TargetDeclTest, BaseSpecifier) { + Code = R"cpp( + struct X {}; + struct Y : [[private]] X {}; + )cpp"; + EXPECT_DECLS("CXXBaseSpecifier", "struct X"); + Code = R"cpp( + struct X {}; + struct Y : [[private X]] {}; + )cpp"; + EXPECT_DECLS("CXXBaseSpecifier", "struct X"); + Code = R"cpp( + struct X {}; + struct Y : private [[X]] {}; + )cpp"; + EXPECT_DECLS("RecordTypeLoc", "struct X"); +} + TEST_F(TargetDeclTest, ConstructorInitList) { Code = R"cpp( struct X { @@ -1027,37 +1045,36 @@ TEST_F(FindExplicitReferencesTest, All) { std::pair</*Code*/ llvm::StringRef, /*References*/ llvm::StringRef> Cases[] = - { - // Simple expressions. - {R"cpp( + {// Simple expressions. + {R"cpp( int global; int func(); void foo(int param) { $0^global = $1^param + $2^func(); } )cpp", - "0: targets = {global}\n" - "1: targets = {param}\n" - "2: targets = {func}\n"}, - {R"cpp( + "0: targets = {global}\n" + "1: targets = {param}\n" + "2: targets = {func}\n"}, + {R"cpp( struct X { int a; }; void foo(X x) { $0^x.$1^a = 10; } )cpp", - "0: targets = {x}\n" - "1: targets = {X::a}\n"}, - {R"cpp( + "0: targets = {x}\n" + "1: targets = {X::a}\n"}, + {R"cpp( // error-ok: testing with broken code int bar(); int foo() { return $0^bar() + $1^bar(42); } )cpp", - "0: targets = {bar}\n" - "1: targets = {bar}\n"}, - // Namespaces and aliases. - {R"cpp( + "0: targets = {bar}\n" + "1: targets = {bar}\n"}, + // Namespaces and aliases. + {R"cpp( namespace ns {} namespace alias = ns; void foo() { @@ -1065,19 +1082,19 @@ using namespace $1^alias; } )cpp", - "0: targets = {ns}\n" - "1: targets = {alias}\n"}, - // Using declarations. - {R"cpp( + "0: targets = {ns}\n" + "1: targets = {alias}\n"}, + // Using declarations. + {R"cpp( namespace ns { int global; } void foo() { using $0^ns::$1^global; } )cpp", - "0: targets = {ns}\n" - "1: targets = {ns::global}, qualifier = 'ns::'\n"}, - // Simple types. - {R"cpp( + "0: targets = {ns}\n" + "1: targets = {ns::global}, qualifier = 'ns::'\n"}, + // Simple types. + {R"cpp( struct Struct { int a; }; using Typedef = int; void foo() { @@ -1086,13 +1103,13 @@ static_cast<$4^Struct*>(0); } )cpp", - "0: targets = {Struct}\n" - "1: targets = {x}, decl\n" - "2: targets = {Typedef}\n" - "3: targets = {y}, decl\n" - "4: targets = {Struct}\n"}, - // Name qualifiers. - {R"cpp( + "0: targets = {Struct}\n" + "1: targets = {x}, decl\n" + "2: targets = {Typedef}\n" + "3: targets = {y}, decl\n" + "4: targets = {Struct}\n"}, + // Name qualifiers. + {R"cpp( namespace a { namespace b { struct S { typedef int type; }; } } void foo() { $0^a::$1^b::$2^S $3^x; @@ -1100,16 +1117,16 @@ $6^S::$7^type $8^y; } )cpp", - "0: targets = {a}\n" - "1: targets = {a::b}, qualifier = 'a::'\n" - "2: targets = {a::b::S}, qualifier = 'a::b::'\n" - "3: targets = {x}, decl\n" - "4: targets = {a}\n" - "5: targets = {a::b}, qualifier = 'a::'\n" - "6: targets = {a::b::S}\n" - "7: targets = {a::b::S::type}, qualifier = 'struct S::'\n" - "8: targets = {y}, decl\n"}, - {R"cpp( + "0: targets = {a}\n" + "1: targets = {a::b}, qualifier = 'a::'\n" + "2: targets = {a::b::S}, qualifier = 'a::b::'\n" + "3: targets = {x}, decl\n" + "4: targets = {a}\n" + "5: targets = {a::b}, qualifier = 'a::'\n" + "6: targets = {a::b::S}\n" + "7: targets = {a::b::S::type}, qualifier = 'struct S::'\n" + "8: targets = {y}, decl\n"}, + {R"cpp( void foo() { $0^ten: // PRINT "HELLO WORLD!" goto $1^ten; @@ -1126,12 +1143,12 @@ $2^vector<bool> $3^vb; } )cpp", - "0: targets = {vector<int>}\n" - "1: targets = {vi}, decl\n" - "2: targets = {vector<bool>}\n" - "3: targets = {vb}, decl\n"}, - // Template type aliases. - {R"cpp( + "0: targets = {vector<int>}\n" + "1: targets = {vi}, decl\n" + "2: targets = {vector<bool>}\n" + "3: targets = {vb}, decl\n"}, + // Template type aliases. + {R"cpp( template <class T> struct vector { using value_type = T; }; template <> struct vector<bool> { using value_type = bool; }; template <class T> using valias = vector<T>; @@ -1140,12 +1157,12 @@ $2^valias<bool> $3^vb; } )cpp", - "0: targets = {valias}\n" - "1: targets = {vi}, decl\n" - "2: targets = {valias}\n" - "3: targets = {vb}, decl\n"}, - // Injected class name. - {R"cpp( + "0: targets = {valias}\n" + "1: targets = {vi}, decl\n" + "2: targets = {valias}\n" + "3: targets = {vb}, decl\n"}, + // Injected class name. + {R"cpp( namespace foo { template <typename $0^T> class $1^Bar { @@ -1154,13 +1171,13 @@ }; } )cpp", - "0: targets = {foo::Bar::T}, decl\n" - "1: targets = {foo::Bar}, decl\n" - "2: targets = {foo::Bar}\n" - "3: targets = {foo::Bar::f}, decl\n" - "4: targets = {foo::Bar}\n"}, - // MemberExpr should know their using declaration. - {R"cpp( + "0: targets = {foo::Bar::T}, decl\n" + "1: targets = {foo::Bar}, decl\n" + "2: targets = {foo::Bar}\n" + "3: targets = {foo::Bar::f}, decl\n" + "4: targets = {foo::Bar}\n"}, + // MemberExpr should know their using declaration. + {R"cpp( struct X { void func(int); }; struct Y : X { using X::func; @@ -1169,10 +1186,10 @@ $0^y.$1^func(1); } )cpp", - "0: targets = {y}\n" - "1: targets = {Y::func}\n"}, - // DeclRefExpr should know their using declaration. - {R"cpp( + "0: targets = {y}\n" + "1: targets = {Y::func}\n"}, + // DeclRefExpr should know their using declaration. + {R"cpp( namespace ns { void bar(int); } using ns::bar; @@ -1180,9 +1197,9 @@ $0^bar(10); } )cpp", - "0: targets = {bar}\n"}, - // References from a macro. - {R"cpp( + "0: targets = {bar}\n"}, + // References from a macro. + {R"cpp( #define FOO a #define BAR b @@ -1190,10 +1207,10 @@ $0^FOO+$1^BAR; } )cpp", - "0: targets = {a}\n" - "1: targets = {b}\n"}, - // No references from implicit nodes. - {R"cpp( + "0: targets = {a}\n" + "1: targets = {b}\n"}, + // No references from implicit nodes. + {R"cpp( struct vector { int *begin(); int *end(); @@ -1205,15 +1222,15 @@ } } )cpp", - "0: targets = {x}, decl\n" - "1: targets = {vector}\n" - "2: targets = {x}\n"}, + "0: targets = {x}, decl\n" + "1: targets = {vector}\n" + "2: targets = {x}\n"}, // Handle UnresolvedLookupExpr. // FIXME // This case fails when expensive checks are enabled. // Seems like the order of ns1::func and ns2::func isn't defined. #ifndef EXPENSIVE_CHECKS - {R"cpp( + {R"cpp( namespace ns1 { void func(char*); } namespace ns2 { void func(int*); } using namespace ns1; @@ -1224,11 +1241,11 @@ $0^func($1^t); } )cpp", - "0: targets = {ns1::func, ns2::func}\n" - "1: targets = {t}\n"}, + "0: targets = {ns1::func, ns2::func}\n" + "1: targets = {t}\n"}, #endif - // Handle UnresolvedMemberExpr. - {R"cpp( + // Handle UnresolvedMemberExpr. + {R"cpp( struct X { void func(char*); void func(int*); @@ -1239,11 +1256,11 @@ $0^x.$1^func($2^t); } )cpp", - "0: targets = {x}\n" - "1: targets = {X::func, X::func}\n" - "2: targets = {t}\n"}, - // Handle DependentScopeDeclRefExpr. - {R"cpp( + "0: targets = {x}\n" + "1: targets = {X::func, X::func}\n" + "2: targets = {t}\n"}, + // Handle DependentScopeDeclRefExpr. + {R"cpp( template <class T> struct S { static int value; @@ -1254,11 +1271,11 @@ $0^S<$1^T>::$2^value; } )cpp", - "0: targets = {S}\n" - "1: targets = {T}\n" - "2: targets = {S::value}, qualifier = 'S<T>::'\n"}, - // Handle CXXDependentScopeMemberExpr. - {R"cpp( + "0: targets = {S}\n" + "1: targets = {T}\n" + "2: targets = {S::value}, qualifier = 'S<T>::'\n"}, + // Handle CXXDependentScopeMemberExpr. + {R"cpp( template <class T> struct S { int value; @@ -1269,10 +1286,10 @@ $0^t.$1^value; } )cpp", - "0: targets = {t}\n" - "1: targets = {S::value}\n"}, - // Type template parameters. - {R"cpp( + "0: targets = {t}\n" + "1: targets = {S::value}\n"}, + // Type template parameters. + {R"cpp( template <class T> void foo() { static_cast<$0^T>(0); @@ -1280,21 +1297,21 @@ $2^T $3^t; } )cpp", - "0: targets = {T}\n" - "1: targets = {T}\n" - "2: targets = {T}\n" - "3: targets = {t}, decl\n"}, - // Non-type template parameters. - {R"cpp( + "0: targets = {T}\n" + "1: targets = {T}\n" + "2: targets = {T}\n" + "3: targets = {t}, decl\n"}, + // Non-type template parameters. + {R"cpp( template <int I> void foo() { int $0^x = $1^I; } )cpp", - "0: targets = {x}, decl\n" - "1: targets = {I}\n"}, - // Template template parameters. - {R"cpp( + "0: targets = {x}, decl\n" + "1: targets = {I}\n"}, + // Template template parameters. + {R"cpp( template <class T> struct vector {}; template <template<class> class TT, template<class> class ...TP> @@ -1305,16 +1322,16 @@ $6^foo<$7^TP...>(); } )cpp", - "0: targets = {TT}\n" - "1: targets = {x}, decl\n" - "2: targets = {foo}\n" - "3: targets = {TT}\n" - "4: targets = {foo}\n" - "5: targets = {vector}\n" - "6: targets = {foo}\n" - "7: targets = {TP}\n"}, - // Non-type template parameters with declarations. - {R"cpp( + "0: targets = {TT}\n" + "1: targets = {x}, decl\n" + "2: targets = {foo}\n" + "3: targets = {TT}\n" + "4: targets = {foo}\n" + "5: targets = {vector}\n" + "6: targets = {foo}\n" + "7: targets = {TP}\n"}, + // Non-type template parameters with declarations. + {R"cpp( int func(); template <int(*)()> struct wrapper {}; @@ -1324,12 +1341,12 @@ $3^FuncParam(); } )cpp", - "0: targets = {wrapper<&func>}\n" - "1: targets = {func}\n" - "2: targets = {w}, decl\n" - "3: targets = {FuncParam}\n"}, - // declaration references. - {R"cpp( + "0: targets = {wrapper<&func>}\n" + "1: targets = {func}\n" + "2: targets = {w}, decl\n" + "3: targets = {FuncParam}\n"}, + // declaration references. + {R"cpp( namespace ns {} class S {}; void foo() { @@ -1341,19 +1358,19 @@ namespace $9^NS = $10^ns; } )cpp", - "0: targets = {Foo}, decl\n" - "1: targets = {foo()::Foo::Foo}, decl\n" - "2: targets = {Foo}\n" - "3: targets = {foo()::Foo::field}, decl\n" - "4: targets = {Var}, decl\n" - "5: targets = {E}, decl\n" - "6: targets = {foo()::ABC}, decl\n" - "7: targets = {INT}, decl\n" - "8: targets = {INT2}, decl\n" - "9: targets = {NS}, decl\n" - "10: targets = {ns}\n"}, - // User-defined conversion operator. - {R"cpp( + "0: targets = {Foo}, decl\n" + "1: targets = {foo()::Foo::Foo}, decl\n" + "2: targets = {Foo}\n" + "3: targets = {foo()::Foo::field}, decl\n" + "4: targets = {Var}, decl\n" + "5: targets = {E}, decl\n" + "6: targets = {foo()::ABC}, decl\n" + "7: targets = {INT}, decl\n" + "8: targets = {INT2}, decl\n" + "9: targets = {NS}, decl\n" + "10: targets = {ns}\n"}, + // User-defined conversion operator. + {R"cpp( void foo() { class $0^Bar {}; class $1^Foo { @@ -1366,18 +1383,18 @@ $7^f.$8^operator $9^Bar(); } )cpp", - "0: targets = {Bar}, decl\n" - "1: targets = {Foo}, decl\n" - "2: targets = {foo()::Foo::operator Bar}, decl\n" - "3: targets = {Bar}\n" - "4: targets = {Bar}\n" - "5: targets = {Foo}\n" - "6: targets = {f}, decl\n" - "7: targets = {f}\n" - "8: targets = {foo()::Foo::operator Bar}\n" - "9: targets = {Bar}\n"}, - // Destructor. - {R"cpp( + "0: targets = {Bar}, decl\n" + "1: targets = {Foo}, decl\n" + "2: targets = {foo()::Foo::operator Bar}, decl\n" + "3: targets = {Bar}\n" + "4: targets = {Bar}\n" + "5: targets = {Foo}\n" + "6: targets = {f}, decl\n" + "7: targets = {f}\n" + "8: targets = {foo()::Foo::operator Bar}\n" + "9: targets = {Bar}\n"}, + // Destructor. + {R"cpp( void foo() { class $0^Foo { public: @@ -1392,18 +1409,18 @@ $6^f.~ /*...*/ $7^Foo(); } )cpp", - "0: targets = {Foo}, decl\n" - // FIXME: It's better to target destructor's FunctionDecl instead of - // the type itself (similar to constructor). - "1: targets = {Foo}\n" - "2: targets = {foo()::Foo::destructMe}, decl\n" - "3: targets = {Foo}\n" - "4: targets = {Foo}\n" - "5: targets = {f}, decl\n" - "6: targets = {f}\n" - "7: targets = {Foo}\n"}, - // cxx constructor initializer. - {R"cpp( + "0: targets = {Foo}, decl\n" + // FIXME: It's better to target destructor's FunctionDecl instead of + // the type itself (similar to constructor). + "1: targets = {Foo}\n" + "2: targets = {foo()::Foo::destructMe}, decl\n" + "3: targets = {Foo}\n" + "4: targets = {Foo}\n" + "5: targets = {f}, decl\n" + "6: targets = {f}\n" + "7: targets = {Foo}\n"}, + // cxx constructor initializer. + {R"cpp( class Base {}; void foo() { // member initializer @@ -1423,34 +1440,34 @@ }; } )cpp", - "0: targets = {X}, decl\n" - "1: targets = {foo()::X::abc}, decl\n" - "2: targets = {foo()::X::X}, decl\n" - "3: targets = {foo()::X::abc}\n" - "4: targets = {Derived}, decl\n" - "5: targets = {Base}\n" - "6: targets = {Base}\n" - "7: targets = {foo()::Derived::B}, decl\n" - "8: targets = {foo()::Derived::Derived}, decl\n" - "9: targets = {Base}\n" - "10: targets = {Foo}, decl\n" - "11: targets = {foo()::Foo::Foo}, decl\n" - "12: targets = {foo()::Foo::Foo}, decl\n" - "13: targets = {Foo}\n"}, - // Anonymous entities should not be reported. - { - R"cpp( + "0: targets = {X}, decl\n" + "1: targets = {foo()::X::abc}, decl\n" + "2: targets = {foo()::X::X}, decl\n" + "3: targets = {foo()::X::abc}\n" + "4: targets = {Derived}, decl\n" + "5: targets = {Base}\n" + "6: targets = {Base}\n" + "7: targets = {foo()::Derived::B}, decl\n" + "8: targets = {foo()::Derived::Derived}, decl\n" + "9: targets = {Base}\n" + "10: targets = {Foo}, decl\n" + "11: targets = {foo()::Foo::Foo}, decl\n" + "12: targets = {foo()::Foo::Foo}, decl\n" + "13: targets = {Foo}\n"}, + // Anonymous entities should not be reported. + { + R"cpp( void foo() { class {} $0^x; int (*$1^fptr)(int $2^a, int) = nullptr; } )cpp", - "0: targets = {x}, decl\n" - "1: targets = {fptr}, decl\n" - "2: targets = {a}, decl\n"}, - // Namespace aliases should be handled properly. - { - R"cpp( + "0: targets = {x}, decl\n" + "1: targets = {fptr}, decl\n" + "2: targets = {a}, decl\n"}, + // Namespace aliases should be handled properly. + { + R"cpp( namespace ns { struct Type {}; } namespace alias = ns; namespace rec_alias = alias; @@ -1461,28 +1478,28 @@ $6^rec_alias::$7^Type $8^c; } )cpp", - "0: targets = {ns}\n" - "1: targets = {ns::Type}, qualifier = 'ns::'\n" - "2: targets = {a}, decl\n" - "3: targets = {alias}\n" - "4: targets = {ns::Type}, qualifier = 'alias::'\n" - "5: targets = {b}, decl\n" - "6: targets = {rec_alias}\n" - "7: targets = {ns::Type}, qualifier = 'rec_alias::'\n" - "8: targets = {c}, decl\n"}, - // Handle SizeOfPackExpr. - { - R"cpp( + "0: targets = {ns}\n" + "1: targets = {ns::Type}, qualifier = 'ns::'\n" + "2: targets = {a}, decl\n" + "3: targets = {alias}\n" + "4: targets = {ns::Type}, qualifier = 'alias::'\n" + "5: targets = {b}, decl\n" + "6: targets = {rec_alias}\n" + "7: targets = {ns::Type}, qualifier = 'rec_alias::'\n" + "8: targets = {c}, decl\n"}, + // Handle SizeOfPackExpr. + { + R"cpp( template <typename... E> void foo() { constexpr int $0^size = sizeof...($1^E); }; )cpp", - "0: targets = {size}, decl\n" - "1: targets = {E}\n"}, - // Class template argument deduction - { - R"cpp( + "0: targets = {size}, decl\n" + "1: targets = {E}\n"}, + // Class template argument deduction + { + R"cpp( template <typename T> struct Test { Test(T); @@ -1491,51 +1508,51 @@ $0^Test $1^a(5); } )cpp", - "0: targets = {Test}\n" - "1: targets = {a}, decl\n"}, - // Templates - {R"cpp( + "0: targets = {Test}\n" + "1: targets = {a}, decl\n"}, + // Templates + {R"cpp( namespace foo { template <typename $0^T> class $1^Bar {}; } )cpp", - "0: targets = {foo::Bar::T}, decl\n" - "1: targets = {foo::Bar}, decl\n"}, - // Templates - {R"cpp( + "0: targets = {foo::Bar::T}, decl\n" + "1: targets = {foo::Bar}, decl\n"}, + // Templates + {R"cpp( namespace foo { template <typename $0^T> void $1^func(); } )cpp", - "0: targets = {T}, decl\n" - "1: targets = {foo::func}, decl\n"}, - // Templates - {R"cpp( + "0: targets = {T}, decl\n" + "1: targets = {foo::func}, decl\n"}, + // Templates + {R"cpp( namespace foo { template <typename $0^T> $1^T $2^x; } )cpp", - "0: targets = {foo::T}, decl\n" - "1: targets = {foo::T}\n" - "2: targets = {foo::x}, decl\n"}, - // Templates - {R"cpp( + "0: targets = {foo::T}, decl\n" + "1: targets = {foo::T}\n" + "2: targets = {foo::x}, decl\n"}, + // Templates + {R"cpp( template<typename T> class vector {}; namespace foo { template <typename $0^T> using $1^V = $2^vector<$3^T>; } )cpp", - "0: targets = {foo::T}, decl\n" - "1: targets = {foo::V}, decl\n" - "2: targets = {vector}\n" - "3: targets = {foo::T}\n"}, - // Concept - { - R"cpp( + "0: targets = {foo::T}, decl\n" + "1: targets = {foo::V}, decl\n" + "2: targets = {vector}\n" + "3: targets = {foo::T}\n"}, + // Concept + { + R"cpp( template <typename T> concept Drawable = requires (T t) { t.draw(); }; @@ -1546,17 +1563,17 @@ } } )cpp", - "0: targets = {T}, decl\n" - "1: targets = {Drawable}\n" - "2: targets = {T}\n" - "3: targets = {foo::bar}, decl\n" - "4: targets = {T}\n" - "5: targets = {t}, decl\n" - "6: targets = {t}\n" - "7: targets = {}\n"}, - // Objective-C: properties - { - R"cpp( + "0: targets = {T}, decl\n" + "1: targets = {Drawable}\n" + "2: targets = {T}\n" + "3: targets = {foo::bar}, decl\n" + "4: targets = {T}\n" + "5: targets = {t}, decl\n" + "6: targets = {t}\n" + "7: targets = {}\n"}, + // Objective-C: properties + { + R"cpp( @interface I {} @property(retain) I* x; @property(retain) I* y; @@ -1566,12 +1583,12 @@ $0^f.$1^x.$2^y = 0; } )cpp", - "0: targets = {f}\n" - "1: targets = {I::x}\n" - "2: targets = {I::y}\n"}, - // Objective-C: implicit properties - { - R"cpp( + "0: targets = {f}\n" + "1: targets = {I::x}\n" + "2: targets = {I::y}\n"}, + // Objective-C: implicit properties + { + R"cpp( @interface I {} -(I*)x; -(void)setY:(I*)y; @@ -1581,11 +1598,11 @@ $0^f.$1^x.$2^y = 0; } )cpp", - "0: targets = {f}\n" - "1: targets = {I::x}\n" - "2: targets = {I::setY:}\n"}, - // Designated initializers. - {R"cpp( + "0: targets = {f}\n" + "1: targets = {I::x}\n" + "2: targets = {I::setY:}\n"}, + // Designated initializers. + {R"cpp( void foo() { struct $0^Foo { int $1^Bar; @@ -1593,12 +1610,12 @@ $2^Foo $3^f { .$4^Bar = 42 }; } )cpp", - "0: targets = {Foo}, decl\n" - "1: targets = {foo()::Foo::Bar}, decl\n" - "2: targets = {Foo}\n" - "3: targets = {f}, decl\n" - "4: targets = {foo()::Foo::Bar}\n"}, - {R"cpp( + "0: targets = {Foo}, decl\n" + "1: targets = {foo()::Foo::Bar}, decl\n" + "2: targets = {Foo}\n" + "3: targets = {f}, decl\n" + "4: targets = {foo()::Foo::Bar}\n"}, + {R"cpp( void foo() { struct $0^Baz { int $1^Field; Index: clang-tools-extra/clangd/FindTarget.cpp =================================================================== --- clang-tools-extra/clangd/FindTarget.cpp +++ clang-tools-extra/clangd/FindTarget.cpp @@ -710,7 +710,8 @@ Finder.add(CCI, Flags); else if (const TemplateArgumentLoc *TAL = N.get<TemplateArgumentLoc>()) Finder.add(TAL->getArgument(), Flags); - + else if (const CXXBaseSpecifier *CBS = N.get<CXXBaseSpecifier>()) + Finder.add(CBS->getTypeSourceInfo()->getType(), Flags); return Finder.takeDecls(); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits