brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · d79c142 Raw
183 lines · cpp
1//===- unittests/Lex/NoTrivialPPDirectiveTracerTest.cpp -------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "clang/Basic/Diagnostic.h"10#include "clang/Basic/DiagnosticOptions.h"11#include "clang/Basic/FileManager.h"12#include "clang/Basic/LangOptions.h"13#include "clang/Basic/SourceManager.h"14#include "clang/Basic/TargetInfo.h"15#include "clang/Basic/TargetOptions.h"16#include "clang/Lex/HeaderSearch.h"17#include "clang/Lex/HeaderSearchOptions.h"18#include "clang/Lex/ModuleLoader.h"19#include "clang/Lex/Preprocessor.h"20#include "clang/Lex/PreprocessorOptions.h"21#include "gtest/gtest.h"22#include <cstddef>23#include <initializer_list>24 25using namespace clang;26 27namespace {28class NoTrivialPPDirectiveTracerTest : public ::testing::Test {29protected:30  NoTrivialPPDirectiveTracerTest()31      : VFS(llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>()),32        FileMgr(FileMgrOpts, VFS),33        Diags(DiagnosticIDs::create(), DiagOpts, new IgnoringDiagConsumer()),34        SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions) {35    TargetOpts->Triple = "x86_64-unknown-linux-gnu";36    Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);37  }38 39  void addFile(const char *source, StringRef Filename) {40    VFS->addFile(Filename, 0, llvm::MemoryBuffer::getMemBuffer(source),41                 /*User=*/std::nullopt,42                 /*Group=*/std::nullopt,43                 llvm::sys::fs::file_type::regular_file);44  }45 46  std::unique_ptr<Preprocessor> getPreprocessor(const char *source,47                                                Language Lang) {48    std::unique_ptr<llvm::MemoryBuffer> Buf =49        llvm::MemoryBuffer::getMemBuffer(source);50    SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));51 52    std::vector<std::string> Includes;53    LangOptions::setLangDefaults(LangOpts, Lang, Target->getTriple(), Includes,54                                 LangStandard::lang_cxx20);55    LangOpts.CPlusPlusModules = true;56    if (Lang != Language::CXX) {57      LangOpts.Modules = true;58      LangOpts.ImplicitModules = true;59    }60 61    HeaderInfo.emplace(HSOpts, SourceMgr, Diags, LangOpts, Target.get());62 63    auto DE = FileMgr.getOptionalDirectoryRef(".");64    assert(DE);65    auto DL = DirectoryLookup(*DE, SrcMgr::C_User, /*isFramework=*/false);66    HeaderInfo->AddSearchPath(DL, /*isAngled=*/false);67 68    return std::make_unique<Preprocessor>(PPOpts, Diags, LangOpts, SourceMgr,69                                          *HeaderInfo, ModLoader,70                                          /*IILookup=*/nullptr,71                                          /*OwnsHeaderSearch=*/false);72  }73 74  IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> VFS;75  FileSystemOptions FileMgrOpts;76  FileManager FileMgr;77  DiagnosticOptions DiagOpts;78  DiagnosticsEngine Diags;79  SourceManager SourceMgr;80  std::shared_ptr<TargetOptions> TargetOpts;81  IntrusiveRefCntPtr<TargetInfo> Target;82  LangOptions LangOpts;83  TrivialModuleLoader ModLoader;84  HeaderSearchOptions HSOpts;85  std::optional<HeaderSearch> HeaderInfo;86  PreprocessorOptions PPOpts;87};88 89TEST_F(NoTrivialPPDirectiveTracerTest, TrivialDirective) {90  const char *source = R"(91    #line 792    # 1 __FILE__ 1 393    #ident "$Header:$"94    #pragma comment(lib, "msvcrt.lib")95    #pragma mark LLVM's world96    #pragma detect_mismatch("test", "1")97    #pragma clang __debug dump Test98    #pragma message "test"99    #pragma GCC warning "Foo"100    #pragma GCC error "Foo"101    #pragma gcc diagnostic push102    #pragma gcc diagnostic pop103    #pragma GCC diagnostic ignored "-Wframe-larger-than"104    #pragma OPENCL EXTENSION __cl_clang_variadic_functions : enable105    #pragma warning(push)106    #pragma warning(pop)107    #pragma execution_character_set(push, "UTF-8")108    #pragma execution_character_set(pop)109    #pragma clang assume_nonnull begin110    #pragma clang assume_nonnull end111    int foo;112  )";113  std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX);114  PP->Initialize(*Target);115  PP->EnterMainSourceFile();116  Token Tok;117  PP->Lex(Tok);118  EXPECT_FALSE(PP->hasSeenNoTrivialPPDirective());119}120 121TEST_F(NoTrivialPPDirectiveTracerTest, IncludeDirective) {122  const char *source = R"(123    #include "header.h"124    int foo;125  )";126  const char *header = R"(127    #ifndef HEADER_H128    #define HEADER_H129    #endif // HEADER_H130  )";131  std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX);132  addFile(header, "header.h");133  PP->Initialize(*Target);134  PP->EnterMainSourceFile();135  Token Tok;136  PP->Lex(Tok);137  EXPECT_TRUE(PP->hasSeenNoTrivialPPDirective());138}139 140TEST_F(NoTrivialPPDirectiveTracerTest, DefineDirective) {141  const char *source = R"(142    #define FOO143    int foo;144  )";145  std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX);146  PP->Initialize(*Target);147  PP->EnterMainSourceFile();148  Token Tok;149  PP->Lex(Tok);150  EXPECT_TRUE(PP->hasSeenNoTrivialPPDirective());151}152 153TEST_F(NoTrivialPPDirectiveTracerTest, UnDefineDirective) {154  const char *source = R"(155    #undef FOO156    int foo;157  )";158  std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX);159  PP->Initialize(*Target);160  PP->setPredefines("#define FOO");161  PP->EnterMainSourceFile();162  Token Tok;163  PP->Lex(Tok);164  EXPECT_TRUE(PP->hasSeenNoTrivialPPDirective());165}166 167TEST_F(NoTrivialPPDirectiveTracerTest, IfDefinedDirective) {168  const char *source = R"(169    #if defined(FOO)170    #endif171    int foo;172  )";173  std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX);174  PP->Initialize(*Target);175  PP->setPredefines("#define FOO");176  PP->EnterMainSourceFile();177  Token Tok;178  PP->Lex(Tok);179  EXPECT_TRUE(PP->hasSeenNoTrivialPPDirective());180}181 182} // namespace183