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"
11 using namespace clang
;
12 using namespace clang::tooling
;
16 class LookupAction
: public ASTFrontendAction
{
17 std::unique_ptr
<ASTConsumer
>
18 CreateASTConsumer(CompilerInstance
&CI
, StringRef
/*Unused*/) override
{
19 return std::make_unique
<clang::ASTConsumer
>();
22 void ExecuteAction() override
{
23 CompilerInstance
&CI
= getCompilerInstance();
24 ASSERT_FALSE(CI
.hasSema());
25 CI
.createSema(getTranslationUnitKind(), nullptr);
26 ASSERT_TRUE(CI
.hasSema());
27 Sema
&S
= CI
.getSema();
30 ASTContext
&Ctx
= S
.getASTContext();
31 auto Name
= &Ctx
.Idents
.get("Foo");
32 LookupResult
R_cpp(S
, Name
, SourceLocation(), Sema::LookupOrdinaryName
);
33 S
.LookupName(R_cpp
, 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());
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_nocpp
, S
.TUScope
, /*AllowBuiltinCreation=*/false,
44 /*ForceNoCPlusPlus=*/true);
45 ASSERT_TRUE(!R_nocpp
.empty());
49 TEST(SemaLookupTest
, ForceNoCPlusPlusPath
) {
50 const char *file_contents
= R
"objcxx(
56 ASSERT_TRUE(runToolOnCodeWithArgs(std::make_unique
<LookupAction
>(),
57 file_contents
, {"-x", "objective-c++"},