clang: lib/CodeGen/ModuleBuilder.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

22#include "llvm/ADT/StringRef.h"

23#include "llvm/IR/DataLayout.h"

24#include "llvm/IR/LLVMContext.h"

25#include "llvm/IR/Module.h"

26#include "llvm/Support/FormatVariadic.h"

27#include "llvm/Support/VirtualFileSystem.h"

28#include

29

30using namespace clang;

32

33namespace {

35 DiagnosticsEngine &Diags;

36 ASTContext *Ctx;

37 IntrusiveRefCntPtrllvm::vfs::FileSystem FS;

38 const HeaderSearchOptions &HeaderSearchOpts;

39 const PreprocessorOptions &PreprocessorOpts;

40 const CodeGenOptions &CodeGenOpts;

41

42 unsigned HandlingTopLevelDecls;

43

44

45

46

47 struct HandlingTopLevelDeclRAII {

48 CodeGeneratorImpl &Self;

49 bool EmitDeferred;

50 HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self,

51 bool EmitDeferred = true)

52 : Self(Self), EmitDeferred(EmitDeferred) {

53 ++Self.HandlingTopLevelDecls;

54 }

55 ~HandlingTopLevelDeclRAII() {

56 unsigned Level = --Self.HandlingTopLevelDecls;

57 if (Level == 0 && EmitDeferred)

58 Self.EmitDeferredDecls();

59 }

60 };

61

62 CoverageSourceInfo *CoverageInfo;

63

64 protected:

65 std::unique_ptrllvm::Module M;

66 std::unique_ptrCodeGen::CodeGenModule Builder;

67

68 private:

69 SmallVector<FunctionDecl *, 8> DeferredInlineMemberFuncDefs;

70

71 static llvm::StringRef ExpandModuleName(llvm::StringRef ModuleName,

72 const CodeGenOptions &CGO) {

73 if (ModuleName == "-" && !CGO.MainFileName.empty())

75 return ModuleName;

76 }

77

78 public:

79 CodeGeneratorImpl(DiagnosticsEngine &diags, llvm::StringRef ModuleName,

80 IntrusiveRefCntPtrllvm::vfs::FileSystem FS,

81 const HeaderSearchOptions &HSO,

82 const PreprocessorOptions &PPO, const CodeGenOptions &CGO,

83 llvm::LLVMContext &C,

84 CoverageSourceInfo *CoverageInfo = nullptr)

85 : Diags(diags), Ctx(nullptr), FS(std::move(FS)), HeaderSearchOpts(HSO),

86 PreprocessorOpts(PPO), CodeGenOpts(CGO), HandlingTopLevelDecls(0),

87 CoverageInfo(CoverageInfo),

88 M(new llvm::Module(ExpandModuleName(ModuleName, CGO), C)) {

89 C.setDiscardValueNames(CGO.DiscardValueNames);

90 }

91

92 ~CodeGeneratorImpl() override {

93

94 assert(DeferredInlineMemberFuncDefs.empty() ||

95 Diags.hasErrorOccurred());

96 }

97

98 CodeGenModule &CGM() {

99 return *Builder;

100 }

101

102 llvm::Module *GetModule() {

103 return M.get();

104 }

105

106 CGDebugInfo *getCGDebugInfo() {

107 return Builder->getModuleDebugInfo();

108 }

109

110 llvm::Module *ReleaseModule() {

111 return M.release();

112 }

113

114 const Decl *GetDeclForMangledName(StringRef MangledName) {

116 if (!Builder->lookupRepresentativeDecl(MangledName, Result))

117 return nullptr;

118 const Decl *D = Result.getCanonicalDecl().getDecl();

119 if (auto FD = dyn_cast(D)) {

120 if (FD->hasBody(FD))

121 return FD;

122 } else if (auto TD = dyn_cast(D)) {

123 if (auto Def = TD->getDefinition())

124 return Def;

125 }

126 return D;

127 }

128

129 llvm::StringRef GetMangledName(GlobalDecl GD) {

130 return Builder->getMangledName(GD);

131 }

132

133 llvm::Constant *GetAddrOfGlobal(GlobalDecl global, bool isForDefinition) {

134 return Builder->GetAddrOfGlobal(global, ForDefinition_t(isForDefinition));

135 }

136

137 llvm::Module *StartModule(llvm::StringRef ModuleName,

138 llvm::LLVMContext &C) {

139 assert(!M && "Replacing existing Module?");

140 M.reset(new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts), C));

141

142 IRGenFinished = false;

143

144 std::unique_ptr OldBuilder = std::move(Builder);

145

146 Initialize(*Ctx);

147

148 if (OldBuilder)

149 OldBuilder->moveLazyEmissionStates(Builder.get());

150

151 return M.get();

152 }

153

154 void Initialize(ASTContext &Context) override {

155 Ctx = &Context;

156

157 M->setTargetTriple(Ctx->getTargetInfo().getTriple());

158 M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString());

160 if (!SDKVersion.empty())

161 M->setSDKVersion(SDKVersion);

162 if (const auto *TVT = Ctx->getTargetInfo().getDarwinTargetVariantTriple())

163 M->setDarwinTargetVariantTriple(TVT->getTriple());

164 if (auto TVSDKVersion =

165 Ctx->getTargetInfo().getDarwinTargetVariantSDKVersion())

166 M->setDarwinTargetVariantSDKVersion(*TVSDKVersion);

167 Builder.reset(new CodeGen::CodeGenModule(Context, FS, HeaderSearchOpts,

168 PreprocessorOpts, CodeGenOpts,

169 *M, Diags, CoverageInfo));

170

171 for (auto &&Lib : CodeGenOpts.DependentLibraries)

172 Builder->AddDependentLib(Lib);

173 for (auto &&Opt : CodeGenOpts.LinkerOptions)

174 Builder->AppendLinkerOptions(Opt);

175 }

176

177 void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {

178 if (Diags.hasErrorOccurred())

179 return;

180

181 Builder->HandleCXXStaticMemberVarInstantiation(VD);

182 }

183

184 bool HandleTopLevelDecl(DeclGroupRef DG) override {

185

186 if (IRGenFinished)

187 return true;

188

189

190 if (Diags.hasUnrecoverableErrorOccurred())

191 return true;

192

193 HandlingTopLevelDeclRAII HandlingDecl(*this);

194

195

196 for (auto &I : DG)

197 Builder->EmitTopLevelDecl(I);

198

199 return true;

200 }

201

202 void EmitDeferredDecls() {

203 if (DeferredInlineMemberFuncDefs.empty())

204 return;

205

206

207

208

209 HandlingTopLevelDeclRAII HandlingDecl(*this);

210 for (unsigned I = 0; I != DeferredInlineMemberFuncDefs.size(); ++I)

211 Builder->EmitTopLevelDecl(DeferredInlineMemberFuncDefs[I]);

212 DeferredInlineMemberFuncDefs.clear();

213 }

214

215 void HandleInlineFunctionDefinition(FunctionDecl *D) override {

216 if (Diags.hasUnrecoverableErrorOccurred())

217 return;

218

220

221

222

223

224

225

226

227

228

229 DeferredInlineMemberFuncDefs.push_back(D);

230

231

232

233

235 Builder->AddDeferredUnusedCoverageMapping(D);

236 }

237

238

239

240

241

242 void HandleTagDeclDefinition(TagDecl *D) override {

243 if (Diags.hasUnrecoverableErrorOccurred())

244 return;

245

246

247

248 HandlingTopLevelDeclRAII HandlingDecl(*this, false);

249

250 Builder->UpdateCompletedType(D);

251

252

253

254 if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()) {

256 if (VarDecl *VD = dyn_cast(Member)) {

257 if (Ctx->isMSStaticDataMemberInlineDefinition(VD) &&

258 Ctx->DeclMustBeEmitted(VD)) {

259 Builder->EmitGlobal(VD);

260 }

261 }

262 }

263 }

264

265 if (Ctx->getLangOpts().OpenMP) {

267 if (auto *DRD = dyn_cast(Member)) {

268 if (Ctx->DeclMustBeEmitted(DRD))

269 Builder->EmitGlobal(DRD);

270 } else if (auto *DMD = dyn_cast(Member)) {

271 if (Ctx->DeclMustBeEmitted(DMD))

272 Builder->EmitGlobal(DMD);

273 }

274 }

275 }

276 }

277

278 void HandleTagDeclRequiredDefinition(const TagDecl *D) override {

279 if (Diags.hasUnrecoverableErrorOccurred())

280 return;

281

282

283

284 HandlingTopLevelDeclRAII HandlingDecl(*this, false);

285

286 if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo())

287 if (const RecordDecl *RD = dyn_cast(D))

288 DI->completeRequiredType(RD);

289 }

290

291 void HandleTranslationUnit(ASTContext &Ctx) override {

292

293 if (!Diags.hasUnrecoverableErrorOccurred() && Builder)

294 Builder->Release();

295

296

297

298 if (Diags.hasErrorOccurred()) {

299 if (Builder)

300 Builder->clear();

301 M.reset();

302 }

303

304 IRGenFinished = true;

305 }

306

307 void AssignInheritanceModel(CXXRecordDecl *RD) override {

308 if (Diags.hasUnrecoverableErrorOccurred())

309 return;

310

311 Builder->RefreshTypeCacheForClass(RD);

312 }

313

314 void CompleteTentativeDefinition(VarDecl *D) override {

315 if (Diags.hasUnrecoverableErrorOccurred())

316 return;

317

318 Builder->EmitTentativeDefinition(D);

319 }

320

321 void CompleteExternalDeclaration(DeclaratorDecl *D) override {

322 Builder->EmitExternalDeclaration(D);

323 }

324

325 void HandleVTable(CXXRecordDecl *RD) override {

326 if (Diags.hasUnrecoverableErrorOccurred())

327 return;

328

329 Builder->EmitVTable(RD);

330 }

331 };

332}

333

334void CodeGenerator::anchor() { }

335

337 return static_cast<CodeGeneratorImpl*>(this)->CGM();

338}

339

341 return static_cast<CodeGeneratorImpl*>(this)->GetModule();

342}

343

345 return static_cast<CodeGeneratorImpl*>(this)->ReleaseModule();

346}

347

349 return static_cast<CodeGeneratorImpl*>(this)->getCGDebugInfo();

350}

351

355

357 return static_cast<CodeGeneratorImpl *>(this)->GetMangledName(GD);

358}

359

361 bool isForDefinition) {

362 return static_cast<CodeGeneratorImpl*>(this)

364}

365

367 llvm::LLVMContext &C) {

368 return static_cast<CodeGeneratorImpl*>(this)->StartModule(ModuleName, C);

369}

370

378 return new CodeGeneratorImpl(Diags, ModuleName, std::move(FS),

379 HeaderSearchOpts, PreprocessorOpts, CGO, C,

380 CoverageInfo);

381}

382

385std::optional<std::pair<StringRef, StringRef>>

387 static auto TrapRegex =

388 llvm::Regex(llvm::formatv("^{0}\\$(.*)\\$(.*)$", ClangTrapPrefix).str());

390 std::string *ErrorPtr = nullptr;

391#ifndef NDEBUG

392 std::string Error;

393 ErrorPtr = &Error;

394#endif

395 if (!TrapRegex.match(FuncName, &Matches, ErrorPtr)) {

396 assert(ErrorPtr && ErrorPtr->empty() && "Invalid regex pattern");

397 return {};

398 }

399

400 if (Matches.size() != 3) {

401 assert(0 && "Expected 3 matches from Regex::match");

402 return {};

403 }

404

405

406 return std::make_pair(Matches[1], Matches[2]);

407}

408}

409}

Defines the clang::ASTContext interface.

Defines the Diagnostic-related interfaces.

constexpr llvm::StringRef ClangTrapPrefix

const TargetInfo & getTargetInfo() const

CodeGenOptions - Track various options which control how the code is optimized and passed to the back...

std::string MainFileName

The user provided name for the "main file", if non-empty.

This class gathers all debug information during compilation and is responsible for emitting to llvm g...

This class organizes the cross-function state that is used while generating LLVM code.

The primary public interface to the Clang code generator.

llvm::Module * ReleaseModule()

Release ownership of the module to the caller.

Definition ModuleBuilder.cpp:344

const Decl * GetDeclForMangledName(llvm::StringRef MangledName)

Given a mangled name, return a declaration which mangles that way which has been added to this code g...

Definition ModuleBuilder.cpp:352

llvm::Module * StartModule(llvm::StringRef ModuleName, llvm::LLVMContext &C)

Create a new llvm::Module after calling HandleTranslationUnit.

Definition ModuleBuilder.cpp:366

llvm::Constant * GetAddrOfGlobal(GlobalDecl decl, bool isForDefinition)

Return the LLVM address of the given global entity.

Definition ModuleBuilder.cpp:360

llvm::StringRef GetMangledName(GlobalDecl GD)

Given a global declaration, return a mangled name for this declaration which has been added to this c...

Definition ModuleBuilder.cpp:356

CodeGen::CGDebugInfo * getCGDebugInfo()

Return debug info code generator.

Definition ModuleBuilder.cpp:348

CodeGen::CodeGenModule & CGM()

Return an opaque reference to the CodeGenModule object, which can be used in various secondary APIs.

Definition ModuleBuilder.cpp:336

llvm::Module * GetModule()

Return the module that this code generator is building into.

Definition ModuleBuilder.cpp:340

Stores additional source code information like skipped ranges which is required by the coverage mappi...

bool isDependentContext() const

Determines whether this context is dependent on a template parameter.

decl_range decls() const

decls_begin/decls_end - Iterate over the declarations stored in this context.

Decl - This represents one declaration (or definition), e.g.

DeclContext * getLexicalDeclContext()

getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).

Concrete class used by the front-end to report problems and issues.

bool doesThisDeclarationHaveABody() const

Returns whether this specific declaration of the function has a body.

GlobalDecl - represents a global declaration.

PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...

const llvm::VersionTuple & getSDKVersion() const

Defines the clang::TargetInfo interface.

@ Decl

The l-value was an access to a declared entity or something equivalently strong, like the address of ...

std::optional< std::pair< StringRef, StringRef > > DemangleTrapReasonInDebugInfo(StringRef FuncName)

Demangle the artificial function name (.

Definition ModuleBuilder.cpp:386

The JSON file list parser is used to communicate input to InstallAPI.

CodeGenerator * CreateLLVMCodeGen(DiagnosticsEngine &Diags, llvm::StringRef ModuleName, IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS, const HeaderSearchOptions &HeaderSearchOpts, const PreprocessorOptions &PreprocessorOpts, const CodeGenOptions &CGO, llvm::LLVMContext &C, CoverageSourceInfo *CoverageInfo=nullptr)

CreateLLVMCodeGen - Create a CodeGenerator instance.

Definition ModuleBuilder.cpp:372

nullptr

This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...

@ Module

Module linkage, which indicates that the entity can be referred to from other translation units withi...

@ Result

The result type of a method or function.