File indexing completed on 2026-05-10 08:36:52
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_CROSSTU_CROSSTRANSLATIONUNIT_H
0015 #define LLVM_CLANG_CROSSTU_CROSSTRANSLATIONUNIT_H
0016
0017 #include "clang/AST/ASTImporterSharedState.h"
0018 #include "clang/Analysis/MacroExpansionContext.h"
0019 #include "clang/Basic/LLVM.h"
0020 #include "llvm/ADT/DenseMap.h"
0021 #include "llvm/ADT/SmallPtrSet.h"
0022 #include "llvm/ADT/StringMap.h"
0023 #include "llvm/Support/Error.h"
0024 #include "llvm/Support/Path.h"
0025 #include <optional>
0026
0027 namespace clang {
0028 class CompilerInstance;
0029 class ASTContext;
0030 class ASTImporter;
0031 class ASTUnit;
0032 class DeclContext;
0033 class FunctionDecl;
0034 class VarDecl;
0035 class NamedDecl;
0036 class TranslationUnitDecl;
0037
0038 namespace cross_tu {
0039
0040 enum class index_error_code {
0041 success = 0,
0042 unspecified = 1,
0043 missing_index_file,
0044 invalid_index_format,
0045 multiple_definitions,
0046 missing_definition,
0047 failed_import,
0048 failed_to_get_external_ast,
0049 failed_to_generate_usr,
0050 triple_mismatch,
0051 lang_mismatch,
0052 lang_dialect_mismatch,
0053 load_threshold_reached,
0054 invocation_list_ambiguous,
0055 invocation_list_file_not_found,
0056 invocation_list_empty,
0057 invocation_list_wrong_format,
0058 invocation_list_lookup_unsuccessful
0059 };
0060
0061 class IndexError : public llvm::ErrorInfo<IndexError> {
0062 public:
0063 static char ID;
0064 IndexError(index_error_code C) : Code(C), LineNo(0) {}
0065 IndexError(index_error_code C, std::string FileName, int LineNo = 0)
0066 : Code(C), FileName(std::move(FileName)), LineNo(LineNo) {}
0067 IndexError(index_error_code C, std::string FileName, std::string TripleToName,
0068 std::string TripleFromName)
0069 : Code(C), FileName(std::move(FileName)),
0070 TripleToName(std::move(TripleToName)),
0071 TripleFromName(std::move(TripleFromName)) {}
0072 void log(raw_ostream &OS) const override;
0073 std::error_code convertToErrorCode() const override;
0074 index_error_code getCode() const { return Code; }
0075 int getLineNum() const { return LineNo; }
0076 std::string getFileName() const { return FileName; }
0077 std::string getTripleToName() const { return TripleToName; }
0078 std::string getTripleFromName() const { return TripleFromName; }
0079
0080 private:
0081 index_error_code Code;
0082 std::string FileName;
0083 int LineNo;
0084 std::string TripleToName;
0085 std::string TripleFromName;
0086 };
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097 llvm::Expected<llvm::StringMap<std::string>>
0098 parseCrossTUIndex(StringRef IndexPath);
0099
0100 std::string createCrossTUIndexString(const llvm::StringMap<std::string> &Index);
0101
0102 using InvocationListTy = llvm::StringMap<llvm::SmallVector<std::string, 32>>;
0103
0104
0105
0106
0107
0108 llvm::Expected<InvocationListTy> parseInvocationList(
0109 StringRef FileContent,
0110 llvm::sys::path::Style PathStyle = llvm::sys::path::Style::posix);
0111
0112
0113
0114
0115 bool shouldImport(const VarDecl *VD, const ASTContext &ACtx);
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127 class CrossTranslationUnitContext {
0128 public:
0129 CrossTranslationUnitContext(CompilerInstance &CI);
0130 ~CrossTranslationUnitContext();
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148 llvm::Expected<const FunctionDecl *>
0149 getCrossTUDefinition(const FunctionDecl *FD, StringRef CrossTUDir,
0150 StringRef IndexName, bool DisplayCTUProgress = false);
0151 llvm::Expected<const VarDecl *>
0152 getCrossTUDefinition(const VarDecl *VD, StringRef CrossTUDir,
0153 StringRef IndexName, bool DisplayCTUProgress = false);
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168 llvm::Expected<ASTUnit *> loadExternalAST(StringRef LookupName,
0169 StringRef CrossTUDir,
0170 StringRef IndexName,
0171 bool DisplayCTUProgress = false);
0172
0173
0174
0175
0176
0177
0178 llvm::Expected<const FunctionDecl *> importDefinition(const FunctionDecl *FD,
0179 ASTUnit *Unit);
0180 llvm::Expected<const VarDecl *> importDefinition(const VarDecl *VD,
0181 ASTUnit *Unit);
0182
0183
0184 static std::optional<std::string> getLookupName(const NamedDecl *ND);
0185
0186
0187 void emitCrossTUDiagnostics(const IndexError &IE);
0188
0189
0190
0191
0192
0193
0194
0195
0196 std::optional<clang::MacroExpansionContext>
0197 getMacroExpansionContextForSourceLocation(
0198 const clang::SourceLocation &ToLoc) const;
0199
0200
0201 bool isImportedAsNew(const Decl *ToDecl) const;
0202
0203
0204
0205
0206 bool hasError(const Decl *ToDecl) const;
0207
0208 private:
0209 void lazyInitImporterSharedSt(TranslationUnitDecl *ToTU);
0210 ASTImporter &getOrCreateASTImporter(ASTUnit *Unit);
0211 template <typename T>
0212 llvm::Expected<const T *> getCrossTUDefinitionImpl(const T *D,
0213 StringRef CrossTUDir,
0214 StringRef IndexName,
0215 bool DisplayCTUProgress);
0216 template <typename T>
0217 const T *findDefInDeclContext(const DeclContext *DC,
0218 StringRef LookupName);
0219 template <typename T>
0220 llvm::Expected<const T *> importDefinitionImpl(const T *D, ASTUnit *Unit);
0221
0222 using ImporterMapTy =
0223 llvm::DenseMap<TranslationUnitDecl *, std::unique_ptr<ASTImporter>>;
0224
0225 ImporterMapTy ASTUnitImporterMap;
0226
0227 ASTContext &Context;
0228 std::shared_ptr<ASTImporterSharedState> ImporterSharedSt;
0229
0230 using LoadResultTy = llvm::Expected<std::unique_ptr<ASTUnit>>;
0231
0232
0233 class ASTLoader {
0234 public:
0235 ASTLoader(CompilerInstance &CI, StringRef CTUDir,
0236 StringRef InvocationListFilePath);
0237
0238
0239
0240
0241
0242 LoadResultTy load(StringRef Identifier);
0243
0244
0245
0246 llvm::Error lazyInitInvocationList();
0247
0248 private:
0249
0250
0251 const llvm::sys::path::Style PathStyle = llvm::sys::path::Style::posix;
0252
0253
0254 LoadResultTy loadFromDump(StringRef Identifier);
0255
0256 LoadResultTy loadFromSource(StringRef Identifier);
0257
0258 CompilerInstance &CI;
0259 StringRef CTUDir;
0260
0261
0262
0263 StringRef InvocationListFilePath;
0264
0265
0266 std::optional<InvocationListTy> InvocationList;
0267 index_error_code PreviousParsingResult = index_error_code::success;
0268 };
0269
0270
0271 class ASTLoadGuard {
0272 public:
0273 ASTLoadGuard(unsigned Limit) : Limit(Limit) {}
0274
0275
0276
0277 operator bool() const { return Count < Limit; }
0278
0279
0280 void indicateLoadSuccess() { ++Count; }
0281
0282 private:
0283
0284 unsigned Count{0u};
0285
0286 const unsigned Limit;
0287 };
0288
0289
0290
0291 class ASTUnitStorage {
0292 public:
0293 ASTUnitStorage(CompilerInstance &CI);
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305 llvm::Expected<ASTUnit *> getASTUnitForFunction(StringRef FunctionName,
0306 StringRef CrossTUDir,
0307 StringRef IndexName,
0308 bool DisplayCTUProgress);
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319 llvm::Expected<std::string> getFileForFunction(StringRef FunctionName,
0320 StringRef CrossTUDir,
0321 StringRef IndexName);
0322
0323 private:
0324 llvm::Error ensureCTUIndexLoaded(StringRef CrossTUDir, StringRef IndexName);
0325 llvm::Expected<ASTUnit *> getASTUnitForFile(StringRef FileName,
0326 bool DisplayCTUProgress);
0327
0328 template <typename... T> using BaseMapTy = llvm::StringMap<T...>;
0329 using OwningMapTy = BaseMapTy<std::unique_ptr<clang::ASTUnit>>;
0330 using NonOwningMapTy = BaseMapTy<clang::ASTUnit *>;
0331
0332 OwningMapTy FileASTUnitMap;
0333 NonOwningMapTy NameASTUnitMap;
0334
0335 using IndexMapTy = BaseMapTy<std::string>;
0336 IndexMapTy NameFileMap;
0337
0338
0339 ASTLoader Loader;
0340
0341
0342
0343
0344
0345 ASTLoadGuard LoadGuard;
0346 };
0347
0348 ASTUnitStorage ASTStorage;
0349 };
0350
0351 }
0352 }
0353
0354 #endif