clang-tools 22.0.0git
ParsedAST.h
Go to the documentation of this file.
1//===--- ParsedAST.h - Building translation units ----------------*- C++-*-===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file exposes building a file as if it were open in clangd, and defines
10// the ParsedAST structure that holds the results.
11//
12// This is similar to a clang -fsyntax-only run that produces a clang AST, but
13// we have several customizations:
14// - preamble handling
15// - capturing diagnostics for later access
16// - running clang-tidy checks
17//
18//===----------------------------------------------------------------------===//
19
20#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_PARSEDAST_H
21#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_PARSEDAST_H
22
23#include "CollectMacros.h"
24#include "Compiler.h"
25#include "Diagnostics.h"
26#include "Headers.h"
27#include "Preamble.h"
28#include "clang-include-cleaner/Record.h"
29#include "support/Path.h"
30#include "clang/Frontend/FrontendAction.h"
31#include "clang/Lex/Preprocessor.h"
32#include "clang/Tooling/Syntax/Tokens.h"
33#include "llvm/ADT/ArrayRef.h"
34#include "llvm/ADT/StringRef.h"
35#include <memory>
36#include <optional>
37#include <string>
38#include <vector>
39
40namespace clang {
41class HeuristicResolver;
42class Sema;
43namespace clangd {
44
45/// Stores and provides access to parsed AST.
46class ParsedAST {
47public:
48 /// Attempts to run Clang and store the parsed AST.
49 /// If \p Preamble is non-null it is reused during parsing.
50 /// This function does not check if preamble is valid to reuse.
51 static std::optional<ParsedAST>
52 build(llvm::StringRef Filename, const ParseInputs &Inputs,
53 std::unique_ptr<clang::CompilerInvocation> CI,
54 llvm::ArrayRef<Diag> CompilerInvocationDiags,
55 std::shared_ptr<const PreambleData> Preamble);
56
59
60 ~ParsedAST();
61
62 ParsedAST(const ParsedAST &Other) = delete;
63 ParsedAST &operator=(const ParsedAST &Other) = delete;
64
65 /// Note that the returned ast will not contain decls from the preamble that
66 /// were not deserialized during parsing. Clients should expect only decls
67 /// from the main file to be in the AST.
68 ASTContext &getASTContext();
69 const ASTContext &getASTContext() const;
70
71 Sema &getSema();
72
73 Preprocessor &getPreprocessor();
74 std::shared_ptr<Preprocessor> getPreprocessorPtr();
75 const Preprocessor &getPreprocessor() const;
76
77 SourceManager &getSourceManager() {
78 return getASTContext().getSourceManager();
79 }
80 const SourceManager &getSourceManager() const {
81 return getASTContext().getSourceManager();
82 }
83
84 const LangOptions &getLangOpts() const {
85 return getASTContext().getLangOpts();
86 }
87
88 /// This function returns top-level decls present in the main file of the AST.
89 /// The result does not include the decls that come from the preamble.
90 /// (These should be const, but RecursiveASTVisitor requires Decl*).
91 ArrayRef<Decl *> getLocalTopLevelDecls();
92 ArrayRef<const Decl *> getLocalTopLevelDecls() const;
93
94 llvm::ArrayRef<Diag> getDiagnostics() const;
95
96 /// Returns the estimated size of the AST and the accessory structures, in
97 /// bytes. Does not include the size of the preamble.
98 std::size_t getUsedBytes() const;
100
101 /// Gets all macro references (definition, expansions) present in the main
102 /// file, including those in the preamble region.
103 const MainFileMacros &getMacros() const;
104 /// Gets all pragma marks in the main file.
105 const std::vector<PragmaMark> &getMarks() const;
106 /// Tokens recorded while parsing the main file.
107 /// (!) does not have tokens from the preamble.
108 const syntax::TokenBuffer &getTokens() const { return Tokens; }
109 /// Returns the PramaIncludes for preamble + main file includes.
110 const include_cleaner::PragmaIncludes &getPragmaIncludes() const;
111
112 /// Returns the version of the ParseInputs this AST was built from.
113 llvm::StringRef version() const { return Version; }
114
115 /// Returns the path passed by the caller when building this AST.
116 PathRef tuPath() const { return TUPath; }
117
118 /// Returns the version of the ParseInputs used to build Preamble part of this
119 /// AST. Might be std::nullopt if no Preamble is used.
120 std::optional<llvm::StringRef> preambleVersion() const;
121
122 const HeuristicResolver *getHeuristicResolver() const {
123 return Resolver.get();
124 }
125
126private:
127 ParsedAST(PathRef TUPath, llvm::StringRef Version,
128 std::shared_ptr<const PreambleData> Preamble,
129 std::unique_ptr<CompilerInstance> Clang,
130 std::unique_ptr<FrontendAction> Action, syntax::TokenBuffer Tokens,
131 MainFileMacros Macros, std::vector<PragmaMark> Marks,
132 std::vector<Decl *> LocalTopLevelDecls, std::vector<Diag> Diags,
133 IncludeStructure Includes, include_cleaner::PragmaIncludes PI);
134 Path TUPath;
135 std::string Version;
136 // In-memory preambles must outlive the AST, it is important that this member
137 // goes before Clang and Action.
138 std::shared_ptr<const PreambleData> Preamble;
139 // We store an "incomplete" FrontendAction (i.e. no EndSourceFile was called
140 // on it) and CompilerInstance used to run it. That way we don't have to do
141 // complex memory management of all Clang structures on our own. (They are
142 // stored in CompilerInstance and cleaned up by
143 // FrontendAction.EndSourceFile).
144 std::unique_ptr<CompilerInstance> Clang;
145 std::unique_ptr<FrontendAction> Action;
146 /// Tokens recorded after the preamble finished.
147 /// - Includes all spelled tokens for the main file.
148 /// - Includes expanded tokens produced **after** preamble.
149 /// - Does not have spelled or expanded tokens for files from preamble.
150 syntax::TokenBuffer Tokens;
151
152 /// All macro definitions and expansions in the main file.
153 MainFileMacros Macros;
154 // Pragma marks in the main file.
155 std::vector<PragmaMark> Marks;
156 // Diags emitted while parsing this AST (including preamble and compiler
157 // invocation).
158 std::vector<Diag> Diags;
159 // Top-level decls inside the current file. Not that this does not include
160 // top-level decls from the preamble.
161 std::vector<Decl *> LocalTopLevelDecls;
162 IncludeStructure Includes;
163 include_cleaner::PragmaIncludes PI;
164 std::unique_ptr<HeuristicResolver> Resolver;
165};
166
167} // namespace clangd
168} // namespace clang
169
170#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_PARSEDAST_H
ParsedAST & operator=(const ParsedAST &Other)=delete
std::size_t getUsedBytes() const
Returns the estimated size of the AST and the accessory structures, in bytes.
PathRef tuPath() const
Returns the path passed by the caller when building this AST.
Definition ParsedAST.h:116
std::optional< llvm::StringRef > preambleVersion() const
Returns the version of the ParseInputs used to build Preamble part of this AST.
llvm::StringRef version() const
Returns the version of the ParseInputs this AST was built from.
Definition ParsedAST.h:113
const include_cleaner::PragmaIncludes & getPragmaIncludes() const
Returns the PramaIncludes for preamble + main file includes.
const std::vector< PragmaMark > & getMarks() const
Gets all pragma marks in the main file.
SourceManager & getSourceManager()
Definition ParsedAST.h:77
ASTContext & getASTContext()
Note that the returned ast will not contain decls from the preamble that were not deserialized during...
const HeuristicResolver * getHeuristicResolver() const
Definition ParsedAST.h:122
const LangOptions & getLangOpts() const
Definition ParsedAST.h:84
static std::optional< ParsedAST > build(llvm::StringRef Filename, const ParseInputs &Inputs, std::unique_ptr< clang::CompilerInvocation > CI, llvm::ArrayRef< Diag > CompilerInvocationDiags, std::shared_ptr< const PreambleData > Preamble)
Attempts to run Clang and store the parsed AST.
llvm::ArrayRef< Diag > getDiagnostics() const
std::shared_ptr< Preprocessor > getPreprocessorPtr()
const syntax::TokenBuffer & getTokens() const
Tokens recorded while parsing the main file.
Definition ParsedAST.h:108
ParsedAST(const ParsedAST &Other)=delete
Preprocessor & getPreprocessor()
ArrayRef< Decl * > getLocalTopLevelDecls()
This function returns top-level decls present in the main file of the AST.
ParsedAST & operator=(ParsedAST &&Other)
const IncludeStructure & getIncludeStructure() const
const SourceManager & getSourceManager() const
Definition ParsedAST.h:80
ParsedAST(ParsedAST &&Other)
const MainFileMacros & getMacros() const
Gets all macro references (definition, expansions) present in the main file, including those in the p...
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
Definition AST.cpp:45
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition Path.h:29
std::string Path
A typedef to represent a file path.
Definition Path.h:26
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Information required to run clang, e.g. to parse AST or do code completion.
Definition Compiler.h:49