r204547 - Emit an update record if we instantiate the definition of a function template
Richard Smith
richard-llvm at metafoo.co.uk
Sat Mar 22 16:33:22 PDT 2014
Author: rsmith
Date: Sat Mar 22 18:33:22 2014
New Revision: 204547
URL: http://llvm.org/viewvc/llvm-project?rev=204547&view=rev
Log:
Emit an update record if we instantiate the definition of a function template
specialization from a module. (This can also happen for function template
specializations in PCHs if they're instantiated eagerly, because they're
constexpr or have a deduced return type.)
Added:
cfe/trunk/test/Modules/Inputs/cxx-irgen-left.h
cfe/trunk/test/Modules/Inputs/cxx-irgen-right.h
cfe/trunk/test/Modules/Inputs/cxx-irgen-top.h
cfe/trunk/test/Modules/cxx-irgen.cpp
Modified:
cfe/trunk/include/clang/AST/ASTMutationListener.h
cfe/trunk/include/clang/Serialization/ASTWriter.h
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/lib/Serialization/ASTCommon.h
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
Modified: cfe/trunk/include/clang/AST/ASTMutationListener.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTMutationListener.h?rev=204547&r1=204546&r2=204547&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTMutationListener.h (original)
+++ cfe/trunk/include/clang/AST/ASTMutationListener.h Sat Mar 22 18:33:22 2014
@@ -78,6 +78,9 @@ public:
/// \brief A static data member was implicitly instantiated.
virtual void StaticDataMemberInstantiated(const VarDecl *D) {}
+ /// \brief A function template's definition was instantiated.
+ virtual void FunctionDefinitionInstantiated(const FunctionDecl *D) {}
+
/// \brief A new objc category class was added for an interface.
virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
const ObjCInterfaceDecl *IFD) {}
Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=204547&r1=204546&r2=204547&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Sat Mar 22 18:33:22 2014
@@ -503,6 +503,7 @@ private:
void WriteDeclsBlockAbbrevs();
void WriteDecl(ASTContext &Context, Decl *D);
+ void AddFunctionDefinition(const FunctionDecl *FD, RecordData &Record);
void WriteASTCore(Sema &SemaRef,
StringRef isysroot, const std::string &OutputFile,
@@ -766,6 +767,7 @@ public:
void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override;
void CompletedImplicitDefinition(const FunctionDecl *D) override;
void StaticDataMemberInstantiated(const VarDecl *D) override;
+ void FunctionDefinitionInstantiated(const FunctionDecl *D) override;
void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
const ObjCInterfaceDecl *IFD) override;
void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=204547&r1=204546&r2=204547&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Sat Mar 22 18:33:22 2014
@@ -12,6 +12,7 @@
#include "clang/Sema/SemaInternal.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/DependentDiagnostic.h"
@@ -3439,7 +3440,8 @@ void Sema::InstantiateFunctionDefinition
PerformDependentDiagnostics(PatternDecl, TemplateArgs);
- // FIXME: Notify the ASTMutationListener that we did this.
+ if (auto *Listener = getASTMutationListener())
+ Listener->FunctionDefinitionInstantiated(Function);
savedContext.pop();
}
Modified: cfe/trunk/lib/Serialization/ASTCommon.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.h?rev=204547&r1=204546&r2=204547&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTCommon.h (original)
+++ cfe/trunk/lib/Serialization/ASTCommon.h Sat Mar 22 18:33:22 2014
@@ -26,6 +26,7 @@ enum DeclUpdateKind {
UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
UPD_CXX_ADDED_ANONYMOUS_NAMESPACE,
UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER,
+ UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION,
UPD_CXX_RESOLVED_EXCEPTION_SPEC,
UPD_CXX_DEDUCED_RETURN_TYPE,
UPD_DECL_MARKED_USED,
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=204547&r1=204546&r2=204547&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Sat Mar 22 18:33:22 2014
@@ -2944,6 +2944,24 @@ void ASTDeclReader::UpdateDecl(Decl *D,
Reader.ReadSourceLocation(ModuleFile, Record, Idx));
break;
+ case UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION: {
+ FunctionDecl *FD = cast<FunctionDecl>(D);
+ if (FD->hasBody() || Reader.PendingBodies[FD])
+ // FIXME: Maybe check for ODR violations.
+ break;
+
+ if (Record[Idx++])
+ FD->setImplicitlyInline();
+ FD->setInnerLocStart(Reader.ReadSourceLocation(ModuleFile, Record, Idx));
+ if (auto *CD = dyn_cast<CXXConstructorDecl>(FD))
+ std::tie(CD->CtorInitializers, CD->NumCtorInitializers) =
+ Reader.ReadCXXCtorInitializers(ModuleFile, Record, Idx);
+ // Store the offset of the body so we can lazily load it later.
+ Reader.PendingBodies[FD] = GetCurrentCursorOffset();
+ assert(Idx == Record.size() && "lazy body must be last");
+ break;
+ }
+
case UPD_CXX_RESOLVED_EXCEPTION_SPEC: {
auto *FD = cast<FunctionDecl>(D);
auto *FPT = FD->getType()->castAs<FunctionProtoType>();
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=204547&r1=204546&r2=204547&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Sat Mar 22 18:33:22 2014
@@ -4358,6 +4358,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(R
OffsetsRecord.push_back(GetDeclRef(D));
OffsetsRecord.push_back(Stream.GetCurrentBitNo());
+ bool HasUpdatedBody = false;
RecordData Record;
for (auto &Update : DeclUpdate.second) {
DeclUpdateKind Kind = (DeclUpdateKind)Update.getKind();
@@ -4374,6 +4375,13 @@ void ASTWriter::WriteDeclUpdatesBlocks(R
AddSourceLocation(Update.getLoc(), Record);
break;
+ case UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION:
+ // An updated body is emitted last, so that the reader doesn't need
+ // to skip over the lazy body to reach statements for other records.
+ Record.pop_back();
+ HasUpdatedBody = true;
+ break;
+
case UPD_CXX_RESOLVED_EXCEPTION_SPEC:
addExceptionSpec(
*this,
@@ -4395,6 +4403,14 @@ void ASTWriter::WriteDeclUpdatesBlocks(R
}
}
+ if (HasUpdatedBody) {
+ const FunctionDecl *Def = cast<FunctionDecl>(D);
+ Record.push_back(UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION);
+ Record.push_back(Def->isInlined());
+ AddSourceLocation(Def->getInnerLocStart(), Record);
+ AddFunctionDefinition(Def, Record);
+ }
+
Stream.EmitRecord(DECL_UPDATES, Record);
// Flush any statements that were written as part of this update record.
@@ -5381,6 +5397,17 @@ void ASTWriter::CompletedImplicitDefinit
RewriteDecl(D);
}
+void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {
+ assert(!WritingAST && "Already writing the AST!");
+ if (!D->isFromASTFile())
+ return;
+
+ // Since the actual instantiation is delayed, this really means that we need
+ // to update the instantiation location.
+ DeclUpdates[D].push_back(
+ DeclUpdate(UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION));
+}
+
void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) {
assert(!WritingAST && "Already writing the AST!");
if (!D->isFromASTFile())
Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=204547&r1=204546&r2=204547&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Sat Mar 22 18:33:22 2014
@@ -130,6 +130,14 @@ namespace clang {
void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
+
+ void AddFunctionDefinition(const FunctionDecl *FD) {
+ assert(FD->doesThisDeclarationHaveABody());
+ if (auto *CD = dyn_cast<CXXConstructorDecl>(FD))
+ Writer.AddCXXCtorInitializers(CD->CtorInitializers,
+ CD->NumCtorInitializers, Record);
+ Writer.AddStmt(FD->getBody());
+ }
};
}
@@ -1894,3 +1902,11 @@ void ASTWriter::WriteDecl(ASTContext &Co
if (isRequiredDecl(D, Context))
EagerlyDeserializedDecls.push_back(ID);
}
+
+void ASTWriter::AddFunctionDefinition(const FunctionDecl *FD,
+ RecordData &Record) {
+ ClearSwitchCaseIDs();
+
+ ASTDeclWriter W(*this, FD->getASTContext(), Record);
+ W.AddFunctionDefinition(FD);
+}
Added: cfe/trunk/test/Modules/Inputs/cxx-irgen-left.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-irgen-left.h?rev=204547&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-irgen-left.h (added)
+++ cfe/trunk/test/Modules/Inputs/cxx-irgen-left.h Sat Mar 22 18:33:22 2014
@@ -0,0 +1,3 @@
+#include "cxx-irgen-top.h"
+
+S<int> s;
Added: cfe/trunk/test/Modules/Inputs/cxx-irgen-right.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-irgen-right.h?rev=204547&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-irgen-right.h (added)
+++ cfe/trunk/test/Modules/Inputs/cxx-irgen-right.h Sat Mar 22 18:33:22 2014
@@ -0,0 +1,3 @@
+#include "cxx-irgen-top.h"
+
+inline int h() { return S<int>::f(); }
Added: cfe/trunk/test/Modules/Inputs/cxx-irgen-top.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-irgen-top.h?rev=204547&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-irgen-top.h (added)
+++ cfe/trunk/test/Modules/Inputs/cxx-irgen-top.h Sat Mar 22 18:33:22 2014
@@ -0,0 +1,6 @@
+template<typename T> struct S {
+ __attribute__((always_inline)) static int f() { return 0; }
+ __attribute__((always_inline, visibility("hidden"))) static int g() { return 0; }
+};
+
+extern template struct S<int>;
Added: cfe/trunk/test/Modules/cxx-irgen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/cxx-irgen.cpp?rev=204547&view=auto
==============================================================================
--- cfe/trunk/test/Modules/cxx-irgen.cpp (added)
+++ cfe/trunk/test/Modules/cxx-irgen.cpp Sat Mar 22 18:33:22 2014
@@ -0,0 +1,15 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -x objective-c++ -fmodules-cache-path=%t -I %S/Inputs -triple %itanium_abi_triple -disable-llvm-optzns -emit-llvm -o - %s | FileCheck %s
+// FIXME: When we have a syntax for modules in C++, use that.
+
+ at import cxx_irgen_top;
+ at import cxx_irgen_left;
+ at import cxx_irgen_right;
+
+// CHECK: define available_externally hidden i32 @_ZN1SIiE1gEv({{.*}} #[[ALWAYS_INLINE:.*]] align
+int a = S<int>::g();
+
+// CHECK: define available_externally i32 @_ZN1SIiE1fEv({{.*}} #[[ALWAYS_INLINE]] align
+int b = h();
+
+// CHECK: attributes #[[ALWAYS_INLINE]] = {{.*}} alwaysinline
More information about the cfe-commits
mailing list