xref: /llvm-project/clang/unittests/Sema/SemaLookupTest.cpp (revision c57f03415f9668f942802ff7108410d57c2b10da)
1*c57f0341SAlex Langford #include "clang/AST/DeclarationName.h"
2*c57f0341SAlex Langford #include "clang/Frontend/CompilerInstance.h"
3*c57f0341SAlex Langford #include "clang/Frontend/FrontendAction.h"
4*c57f0341SAlex Langford #include "clang/Parse/ParseAST.h"
5*c57f0341SAlex Langford #include "clang/Sema/Lookup.h"
6*c57f0341SAlex Langford #include "clang/Sema/Sema.h"
7*c57f0341SAlex Langford #include "clang/Tooling/Tooling.h"
8*c57f0341SAlex Langford #include "gtest/gtest.h"
9*c57f0341SAlex Langford 
10*c57f0341SAlex Langford using namespace llvm;
11*c57f0341SAlex Langford using namespace clang;
12*c57f0341SAlex Langford using namespace clang::tooling;
13*c57f0341SAlex Langford 
14*c57f0341SAlex Langford namespace {
15*c57f0341SAlex Langford 
16*c57f0341SAlex Langford class LookupAction : public ASTFrontendAction {
17*c57f0341SAlex Langford   std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,StringRef)18*c57f0341SAlex Langford   CreateASTConsumer(CompilerInstance &CI, StringRef /*Unused*/) override {
19*c57f0341SAlex Langford     return std::make_unique<clang::ASTConsumer>();
20*c57f0341SAlex Langford   }
21*c57f0341SAlex Langford 
ExecuteAction()22*c57f0341SAlex Langford   void ExecuteAction() override {
23*c57f0341SAlex Langford     CompilerInstance &CI = getCompilerInstance();
24*c57f0341SAlex Langford     ASSERT_FALSE(CI.hasSema());
25*c57f0341SAlex Langford     CI.createSema(getTranslationUnitKind(), nullptr);
26*c57f0341SAlex Langford     ASSERT_TRUE(CI.hasSema());
27*c57f0341SAlex Langford     Sema &S = CI.getSema();
28*c57f0341SAlex Langford     ParseAST(S);
29*c57f0341SAlex Langford 
30*c57f0341SAlex Langford     ASTContext &Ctx = S.getASTContext();
31*c57f0341SAlex Langford     auto Name = &Ctx.Idents.get("Foo");
32*c57f0341SAlex Langford     LookupResult R_cpp(S, Name, SourceLocation(), Sema::LookupOrdinaryName);
33*c57f0341SAlex Langford     S.LookupName(R_cpp, S.TUScope, /*AllowBuiltinCreation=*/false,
34*c57f0341SAlex Langford                  /*ForceNoCPlusPlus=*/false);
35*c57f0341SAlex Langford     // By this point, parsing is done and S.TUScope is nullptr
36*c57f0341SAlex Langford     // CppLookupName will perform an early return with no results if the Scope
37*c57f0341SAlex Langford     // we pass in is nullptr. We expect to find nothing.
38*c57f0341SAlex Langford     ASSERT_TRUE(R_cpp.empty());
39*c57f0341SAlex Langford 
40*c57f0341SAlex Langford     // On the other hand, the non-C++ path doesn't care if the Scope passed in
41*c57f0341SAlex Langford     // is nullptr. We'll force the non-C++ path with a flag.
42*c57f0341SAlex Langford     LookupResult R_nocpp(S, Name, SourceLocation(), Sema::LookupOrdinaryName);
43*c57f0341SAlex Langford     S.LookupName(R_nocpp, S.TUScope, /*AllowBuiltinCreation=*/false,
44*c57f0341SAlex Langford                  /*ForceNoCPlusPlus=*/true);
45*c57f0341SAlex Langford     ASSERT_TRUE(!R_nocpp.empty());
46*c57f0341SAlex Langford   }
47*c57f0341SAlex Langford };
48*c57f0341SAlex Langford 
TEST(SemaLookupTest,ForceNoCPlusPlusPath)49*c57f0341SAlex Langford TEST(SemaLookupTest, ForceNoCPlusPlusPath) {
50*c57f0341SAlex Langford   const char *file_contents = R"objcxx(
51*c57f0341SAlex Langford @protocol Foo
52*c57f0341SAlex Langford @end
53*c57f0341SAlex Langford @interface Foo <Foo>
54*c57f0341SAlex Langford @end
55*c57f0341SAlex Langford   )objcxx";
56*c57f0341SAlex Langford   ASSERT_TRUE(runToolOnCodeWithArgs(std::make_unique<LookupAction>(),
57*c57f0341SAlex Langford                                     file_contents, {"-x", "objective-c++"},
58*c57f0341SAlex Langford                                     "test.mm"));
59*c57f0341SAlex Langford }
60*c57f0341SAlex Langford } // namespace
61