93 lines · cpp
1//===- unittests/Lex/PPMemoryAllocationsTest.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 23using namespace clang;24 25namespace {26 27class PPMemoryAllocationsTest : public ::testing::Test {28protected:29 PPMemoryAllocationsTest()30 : FileMgr(FileMgrOpts),31 Diags(DiagnosticIDs::create(), DiagOpts, new IgnoringDiagConsumer()),32 SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions) {33 TargetOpts->Triple = "x86_64-apple-darwin11.1.0";34 Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);35 }36 37 FileSystemOptions FileMgrOpts;38 FileManager FileMgr;39 DiagnosticOptions DiagOpts;40 DiagnosticsEngine Diags;41 SourceManager SourceMgr;42 LangOptions LangOpts;43 std::shared_ptr<TargetOptions> TargetOpts;44 IntrusiveRefCntPtr<TargetInfo> Target;45};46 47TEST_F(PPMemoryAllocationsTest, PPMacroDefinesAllocations) {48 std::string Source;49 size_t NumMacros = 1000000;50 {51 llvm::raw_string_ostream SourceOS(Source);52 53 // Create a combination of 1 or 3 token macros.54 for (size_t I = 0; I < NumMacros; ++I) {55 SourceOS << "#define MACRO_ID_" << I << " ";56 if ((I % 2) == 0)57 SourceOS << "(" << I << ")";58 else59 SourceOS << I;60 SourceOS << "\n";61 }62 }63 64 std::unique_ptr<llvm::MemoryBuffer> Buf =65 llvm::MemoryBuffer::getMemBuffer(Source);66 SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));67 68 HeaderSearchOptions HSOpts;69 TrivialModuleLoader ModLoader;70 HeaderSearch HeaderInfo(HSOpts, SourceMgr, Diags, LangOpts, Target.get());71 PreprocessorOptions PPOpts;72 Preprocessor PP(PPOpts, Diags, LangOpts, SourceMgr, HeaderInfo, ModLoader,73 /*IILookup =*/nullptr,74 /*OwnsHeaderSearch =*/false);75 PP.Initialize(*Target);76 PP.EnterMainSourceFile();77 78 PP.LexTokensUntilEOF();79 80 size_t NumAllocated = PP.getPreprocessorAllocator().getBytesAllocated();81 float BytesPerDefine = float(NumAllocated) / float(NumMacros);82 llvm::errs() << "Num preprocessor allocations for " << NumMacros83 << " #define: " << NumAllocated << "\n";84 llvm::errs() << "Bytes per #define: " << BytesPerDefine << "\n";85 // On arm64-apple-macos, we get around 120 bytes per define.86 // Assume a reasonable upper bound based on that number that we don't want87 // to exceed when storing information about a macro #define with 1 or 388 // tokens.89 EXPECT_LT(BytesPerDefine, 130.0f);90}91 92} // anonymous namespace93