|  | #include "clang/AST/DeclarationName.h" | 
|  | #include "clang/Frontend/CompilerInstance.h" | 
|  | #include "clang/Frontend/FrontendAction.h" | 
|  | #include "clang/Parse/ParseAST.h" | 
|  | #include "clang/Sema/Lookup.h" | 
|  | #include "clang/Sema/Sema.h" | 
|  | #include "clang/Tooling/Tooling.h" | 
|  | #include "gtest/gtest.h" | 
|  |  | 
|  | using namespace llvm; | 
|  | using namespace clang; | 
|  | using namespace clang::tooling; | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | class LookupAction : public ASTFrontendAction { | 
|  | std::unique_ptr<ASTConsumer> | 
|  | CreateASTConsumer(CompilerInstance &CI, StringRef /*Unused*/) override { | 
|  | return std::make_unique<clang::ASTConsumer>(); | 
|  | } | 
|  |  | 
|  | void ExecuteAction() override { | 
|  | CompilerInstance &CI = getCompilerInstance(); | 
|  | ASSERT_FALSE(CI.hasSema()); | 
|  | CI.createSema(getTranslationUnitKind(), nullptr); | 
|  | ASSERT_TRUE(CI.hasSema()); | 
|  | Sema &S = CI.getSema(); | 
|  | ParseAST(S); | 
|  |  | 
|  | ASTContext &Ctx = S.getASTContext(); | 
|  | auto Name = &Ctx.Idents.get("Foo"); | 
|  | LookupResult R_cpp(S, Name, SourceLocation(), Sema::LookupOrdinaryName); | 
|  | S.LookupName(R_cpp, S.TUScope, /*AllowBuiltinCreation=*/false, | 
|  | /*ForceNoCPlusPlus=*/false); | 
|  | // By this point, parsing is done and S.TUScope is nullptr | 
|  | // CppLookupName will perform an early return with no results if the Scope | 
|  | // we pass in is nullptr. We expect to find nothing. | 
|  | ASSERT_TRUE(R_cpp.empty()); | 
|  |  | 
|  | // On the other hand, the non-C++ path doesn't care if the Scope passed in | 
|  | // is nullptr. We'll force the non-C++ path with a flag. | 
|  | LookupResult R_nocpp(S, Name, SourceLocation(), Sema::LookupOrdinaryName); | 
|  | S.LookupName(R_nocpp, S.TUScope, /*AllowBuiltinCreation=*/false, | 
|  | /*ForceNoCPlusPlus=*/true); | 
|  | ASSERT_TRUE(!R_nocpp.empty()); | 
|  | } | 
|  | }; | 
|  |  | 
|  | TEST(SemaLookupTest, ForceNoCPlusPlusPath) { | 
|  | const char *file_contents = R"objcxx( | 
|  | @protocol Foo | 
|  | @end | 
|  | @interface Foo <Foo> | 
|  | @end | 
|  | )objcxx"; | 
|  | ASSERT_TRUE(runToolOnCodeWithArgs(std::make_unique<LookupAction>(), | 
|  | file_contents, {"-x", "objective-c++"}, | 
|  | "test.mm")); | 
|  | } | 
|  | } // namespace |