aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenModule.h
diff options
context:
space:
mode:
authorVassil Vassilev <v.g.vassilev@gmail.com>2022-06-08 09:59:40 +0000
committerVassil Vassilev <v.g.vassilev@gmail.com>2022-12-03 07:18:07 +0000
commitdc4889357adb1b909b986b7d2f2a4b9a2cc40c8e (patch)
treedc385225ac4e9901673fe32ac052c23766c3448f /clang/lib/CodeGen/CodeGenModule.h
parente324a80fab627dd04a454812fcb84f6b9af12546 (diff)
downloadllvm-dc4889357adb1b909b986b7d2f2a4b9a2cc40c8e.zip
llvm-dc4889357adb1b909b986b7d2f2a4b9a2cc40c8e.tar.gz
llvm-dc4889357adb1b909b986b7d2f2a4b9a2cc40c8e.tar.bz2
[clang-repl] Support statements on global scope in incremental mode.
This patch teaches clang to parse statements on the global scope to allow: ``` ./bin/clang-repl clang-repl> int i = 12; clang-repl> ++i; clang-repl> extern "C" int printf(const char*,...); clang-repl> printf("%d\n", i); 13 clang-repl> %quit ``` Generally, disambiguating between statements and declarations is a non-trivial task for a C++ parser. The challenge is to allow both standard C++ to be translated as if this patch does not exist and in the cases where the user typed a statement to be executed as if it were in a function body. Clang's Parser does pretty well in disambiguating between declarations and expressions. We have added DisambiguatingWithExpression flag which allows us to preserve the existing and optimized behavior where needed and implement the extra rules for disambiguating. Only few cases require additional attention: * Constructors/destructors -- Parser::isConstructorDeclarator was used in to disambiguate between ctor-looking declarations and statements on the global scope(eg. `Ns::f()`). * The template keyword -- the template keyword can appear in both declarations and statements. This patch considers the template keyword to be a declaration starter which breaks a few cases in incremental mode which will be tackled later. * The inline (and similar) keyword -- looking at the first token in many cases allows us to classify what is a declaration. * Other language keywords and specifiers -- ObjC/ObjC++/OpenCL/OpenMP rely on pragmas or special tokens which will be handled in subsequent patches. The patch conceptually models a "top-level" statement into a TopLevelStmtDecl. The TopLevelStmtDecl is lowered into a void function with no arguments. We attach this function to the global initializer list to execute the statement blocks in the correct order. Differential revision: https://reviews.llvm.org/D127284
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.h')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h6
1 files changed, 6 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 1c23ffe..8513676 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -591,6 +591,11 @@ private:
llvm::DenseMap<const llvm::Constant *, llvm::GlobalVariable *> RTTIProxyMap;
+ // Helps squashing blocks of TopLevelStmtDecl into a single llvm::Function
+ // when used with -fincremental-extensions.
+ std::pair<std::unique_ptr<CodeGenFunction>, const TopLevelStmtDecl *>
+ GlobalTopLevelStmtBlockInFlight;
+
public:
CodeGenModule(ASTContext &C, IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
const HeaderSearchOptions &headersearchopts,
@@ -1590,6 +1595,7 @@ private:
void EmitDeclContext(const DeclContext *DC);
void EmitLinkageSpec(const LinkageSpecDecl *D);
+ void EmitTopLevelStmt(const TopLevelStmtDecl *D);
/// Emit the function that initializes C++ thread_local variables.
void EmitCXXThreadLocalInitFunc();