summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CodeGenAction.cpp14
-rw-r--r--clang/lib/CodeGen/ModuleBuilder.cpp25
-rw-r--r--clang/lib/Frontend/MultiplexConsumer.cpp5
-rw-r--r--clang/lib/Parse/ParseCXXInlineMethods.cpp3
-rw-r--r--clang/lib/Sema/SemaDecl.cpp4
5 files changed, 40 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp
index 5c0b6a9fd8e..2fe984226e1 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -11,6 +11,7 @@
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclGroup.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
@@ -104,6 +105,19 @@ namespace clang {
return true;
}
+ void HandleInlineMethodDefinition(CXXMethodDecl *D) override {
+ PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
+ Context->getSourceManager(),
+ "LLVM IR generation of inline method");
+ if (llvm::TimePassesIsEnabled)
+ LLVMIRGeneration.startTimer();
+
+ Gen->HandleInlineMethodDefinition(D);
+
+ if (llvm::TimePassesIsEnabled)
+ LLVMIRGeneration.stopTimer();
+ }
+
void HandleTranslationUnit(ASTContext &C) override {
{
PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp
index 7873f44f1de..78cb82dc558 100644
--- a/clang/lib/CodeGen/ModuleBuilder.cpp
+++ b/clang/lib/CodeGen/ModuleBuilder.cpp
@@ -81,6 +81,20 @@ namespace {
return true;
}
+ void HandleInlineMethodDefinition(CXXMethodDecl *D) override {
+ if (Diags.hasErrorOccurred())
+ return;
+
+ assert(D->doesThisDeclarationHaveABody());
+
+ // We may have member functions that need to be emitted at this point.
+ if (!D->isDependentContext() &&
+ (D->hasAttr<UsedAttr>() || D->hasAttr<ConstructorAttr>() ||
+ D->hasAttr<DLLExportAttr>())) {
+ Builder->EmitTopLevelDecl(D);
+ }
+ }
+
/// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
/// to (e.g. struct, union, enum, class) is completed. This allows the
/// client hack on the type, which can occur at any point in the file
@@ -90,17 +104,6 @@ namespace {
return;
Builder->UpdateCompletedType(D);
-
- // In C++, we may have member functions that need to be emitted at this
- // point.
- if (Ctx->getLangOpts().CPlusPlus && !D->isDependentContext()) {
- for (auto *M : D->decls())
- if (auto *Method = dyn_cast<CXXMethodDecl>(M))
- if (Method->doesThisDeclarationHaveABody() &&
- (Method->hasAttr<UsedAttr>() ||
- Method->hasAttr<ConstructorAttr>()))
- Builder->EmitTopLevelDecl(Method);
- }
}
void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
diff --git a/clang/lib/Frontend/MultiplexConsumer.cpp b/clang/lib/Frontend/MultiplexConsumer.cpp
index 4b4804f0350..058cee8244b 100644
--- a/clang/lib/Frontend/MultiplexConsumer.cpp
+++ b/clang/lib/Frontend/MultiplexConsumer.cpp
@@ -226,6 +226,11 @@ bool MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) {
return Continue;
}
+void MultiplexConsumer::HandleInlineMethodDefinition(CXXMethodDecl *D) {
+ for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+ Consumers[i]->HandleInlineMethodDefinition(D);
+}
+
void MultiplexConsumer::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) {
for (size_t i = 0, e = Consumers.size(); i != e; ++i)
Consumers[i]->HandleCXXStaticMemberVarInstantiation(VD);
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 8b368cc4054..19aa664031d 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -467,6 +467,9 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
ConsumeAnyToken();
}
+
+ if (CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(LM.D))
+ Actions.ActOnFinishInlineMethodDef(MD);
}
/// ParseLexedMemberInitializers - We finished parsing the member specification
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a522ef4784b..d7b5ba427d6 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9515,6 +9515,10 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
return ActOnStartOfFunctionDef(FnBodyScope, DP);
}
+void Sema::ActOnFinishInlineMethodDef(CXXMethodDecl *D) {
+ Consumer.HandleInlineMethodDefinition(D);
+}
+
static bool ShouldWarnAboutMissingPrototype(const FunctionDecl *FD,
const FunctionDecl*& PossibleZeroParamPrototype) {
// Don't warn about invalid declarations.
OpenPOWER on IntegriCloud