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