forked from microsoft/clang
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Cross Translation Unit support library
This patch introduces a class that can help to build tools that require cross translation unit facilities. This class allows function definitions to be loaded from external AST files based on an index. In order to use this functionality an index is required. The index format is a flat text file but it might be replaced with a different solution in the near future. USRs are used as names to look up the functions definitions. This class also does caching to avoid redundant loading of AST files. Right now only function defnitions can be loaded using this API because this is what the in progress cross translation unit feature of the Static Analyzer requires. In to future this might be extended to classes, types etc. Differential Revision: https://reviews.llvm.org/D34512 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@313975 91177308-0d34-0410-b5e6-96231b3b80d8
- Loading branch information
Showing
22 changed files
with
827 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
//==--- DiagnosticCrossTUKinds.td - Cross Translation Unit diagnostics ----===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
let Component = "CrossTU" in { | ||
|
||
def err_fnmap_parsing : Error< | ||
"error parsing index file: '%0' line: %1 'UniqueID filename' format " | ||
"expected">; | ||
|
||
def err_multiple_def_index : Error< | ||
"multiple definitions are found for the same key in index ">; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
//===--- CrossTUDiagnostic.h - Diagnostics for Cross TU ---------*- C++ -*-===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_CLANG_CROSSTU_CROSSTUDIAGNOSTIC_H | ||
#define LLVM_CLANG_CROSSTU_CROSSTUDIAGNOSTIC_H | ||
|
||
#include "clang/Basic/Diagnostic.h" | ||
|
||
namespace clang { | ||
namespace diag { | ||
enum { | ||
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \ | ||
SHOWINSYSHEADER, CATEGORY) \ | ||
ENUM, | ||
#define CROSSTUSTART | ||
#include "clang/Basic/DiagnosticCrossTUKinds.inc" | ||
#undef DIAG | ||
NUM_BUILTIN_CROSSTU_DIAGNOSTICS | ||
}; | ||
} // end namespace diag | ||
} // end namespace clang | ||
|
||
#endif // LLVM_CLANG_FRONTEND_FRONTENDDIAGNOSTIC_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
//===--- CrossTranslationUnit.h - -------------------------------*- C++ -*-===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file provides an interface to load binary AST dumps on demand. This | ||
// feature can be utilized for tools that require cross translation unit | ||
// support. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
#ifndef LLVM_CLANG_CROSSTU_CROSSTRANSLATIONUNIT_H | ||
#define LLVM_CLANG_CROSSTU_CROSSTRANSLATIONUNIT_H | ||
|
||
#include "clang/Basic/LLVM.h" | ||
#include "llvm/ADT/DenseMap.h" | ||
#include "llvm/ADT/SmallPtrSet.h" | ||
#include "llvm/ADT/StringMap.h" | ||
#include "llvm/Support/Error.h" | ||
|
||
namespace clang { | ||
class CompilerInstance; | ||
class ASTContext; | ||
class ASTImporter; | ||
class ASTUnit; | ||
class DeclContext; | ||
class FunctionDecl; | ||
class NamedDecl; | ||
class TranslationUnitDecl; | ||
|
||
namespace cross_tu { | ||
|
||
enum class index_error_code { | ||
unspecified = 1, | ||
missing_index_file, | ||
invalid_index_format, | ||
multiple_definitions, | ||
missing_definition, | ||
failed_import, | ||
failed_to_get_external_ast, | ||
failed_to_generate_usr | ||
}; | ||
|
||
class IndexError : public llvm::ErrorInfo<IndexError> { | ||
public: | ||
static char ID; | ||
IndexError(index_error_code C) : Code(C), LineNo(0) {} | ||
IndexError(index_error_code C, std::string FileName, int LineNo = 0) | ||
: Code(C), FileName(std::move(FileName)), LineNo(LineNo) {} | ||
void log(raw_ostream &OS) const override; | ||
std::error_code convertToErrorCode() const override; | ||
index_error_code getCode() const { return Code; } | ||
int getLineNum() const { return LineNo; } | ||
std::string getFileName() const { return FileName; } | ||
|
||
private: | ||
index_error_code Code; | ||
std::string FileName; | ||
int LineNo; | ||
}; | ||
|
||
/// \brief This function parses an index file that determines which | ||
/// translation unit contains which definition. | ||
/// | ||
/// The index file format is the following: | ||
/// each line consists of an USR and a filepath separated by a space. | ||
/// | ||
/// \return Returns a map where the USR is the key and the filepath is the value | ||
/// or an error. | ||
llvm::Expected<llvm::StringMap<std::string>> | ||
parseCrossTUIndex(StringRef IndexPath, StringRef CrossTUDir); | ||
|
||
std::string createCrossTUIndexString(const llvm::StringMap<std::string> &Index); | ||
|
||
/// \brief This class is used for tools that requires cross translation | ||
/// unit capability. | ||
/// | ||
/// This class can load function definitions from external AST files. | ||
/// The loaded definition will be merged back to the original AST using the | ||
/// AST Importer. | ||
/// In order to use this class, an index file is required that describes | ||
/// the locations of the AST files for each function definition. | ||
/// | ||
/// Note that this class also implements caching. | ||
class CrossTranslationUnitContext { | ||
public: | ||
CrossTranslationUnitContext(CompilerInstance &CI); | ||
~CrossTranslationUnitContext(); | ||
|
||
/// \brief This function loads a function definition from an external AST | ||
/// file and merge it into the original AST. | ||
/// | ||
/// This method should only be used on functions that have no definitions in | ||
/// the current translation unit. A function definition with the same | ||
/// declaration will be looked up in the index file which should be in the | ||
/// \p CrossTUDir directory, called \p IndexName. In case the declaration is | ||
/// found in the index the corresponding AST file will be loaded and the | ||
/// definition of the function will be merged into the original AST using | ||
/// the AST Importer. | ||
/// | ||
/// \return The declaration with the definition will be returned. | ||
/// If no suitable definition is found in the index file or multiple | ||
/// definitions found error will be returned. | ||
/// | ||
/// Note that the AST files should also be in the \p CrossTUDir. | ||
llvm::Expected<const FunctionDecl *> | ||
getCrossTUDefinition(const FunctionDecl *FD, StringRef CrossTUDir, | ||
StringRef IndexName); | ||
|
||
/// \brief This function loads a function definition from an external AST | ||
/// file. | ||
/// | ||
/// A function definition with the same declaration will be looked up in the | ||
/// index file which should be in the \p CrossTUDir directory, called | ||
/// \p IndexName. In case the declaration is found in the index the | ||
/// corresponding AST file will be loaded. | ||
/// | ||
/// \return Returns an ASTUnit that contains the definition of the looked up | ||
/// function. | ||
/// | ||
/// Note that the AST files should also be in the \p CrossTUDir. | ||
llvm::Expected<ASTUnit *> loadExternalAST(StringRef LookupName, | ||
StringRef CrossTUDir, | ||
StringRef IndexName); | ||
|
||
/// \brief This function merges a definition from a separate AST Unit into | ||
/// the current one which was created by the compiler instance that | ||
/// was passed to the constructor. | ||
/// | ||
/// \return Returns the resulting definition or an error. | ||
llvm::Expected<const FunctionDecl *> importDefinition(const FunctionDecl *FD); | ||
|
||
/// \brief Get a name to identify a function. | ||
static std::string getLookupName(const NamedDecl *ND); | ||
|
||
/// \brief Emit diagnostics for the user for potential configuration errors. | ||
void emitCrossTUDiagnostics(const IndexError &IE); | ||
|
||
private: | ||
ASTImporter &getOrCreateASTImporter(ASTContext &From); | ||
const FunctionDecl *findFunctionInDeclContext(const DeclContext *DC, | ||
StringRef LookupFnName); | ||
|
||
llvm::StringMap<std::unique_ptr<clang::ASTUnit>> FileASTUnitMap; | ||
llvm::StringMap<clang::ASTUnit *> FunctionASTUnitMap; | ||
llvm::StringMap<std::string> FunctionFileMap; | ||
llvm::DenseMap<TranslationUnitDecl *, std::unique_ptr<ASTImporter>> | ||
ASTUnitImporterMap; | ||
CompilerInstance &CI; | ||
ASTContext &Context; | ||
}; | ||
|
||
} // namespace cross_tu | ||
} // namespace clang | ||
|
||
#endif // LLVM_CLANG_CROSSTU_CROSSTRANSLATIONUNIT_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
set(LLVM_LINK_COMPONENTS | ||
Support | ||
) | ||
|
||
add_clang_library(clangCrossTU | ||
CrossTranslationUnit.cpp | ||
|
||
LINK_LIBS | ||
clangAST | ||
clangBasic | ||
clangFrontend | ||
clangIndex | ||
) |
Oops, something went wrong.