/// IDs).
IDENTIFIER_TABLE = 5,
- /// \brief Record code for the array of external definitions.
+ /// \brief Record code for the array of eagerly deserialized decls.
///
- /// The AST file contains a list of all of the unnamed external
- /// definitions present within the parsed headers, stored as an
- /// array of declaration IDs. These external definitions will be
+ /// The AST file contains a list of all of the declarations that should be
+ /// eagerly deserialized present within the parsed headers, stored as an
+ /// array of declaration IDs. These declarations will be
/// reported to the AST consumer after the AST file has been
/// read, since their presence can affect the semantics of the
/// program (e.g., for code generation).
- EXTERNAL_DEFINITIONS = 6,
+ EAGERLY_DESERIALIZED_DECLS = 6,
/// \brief Record code for the set of non-builtin, special
/// types.
/// \brief The IDs of all declarations that fulfill the criteria of
/// "interesting" decls.
///
- /// This contains the data loaded from all EXTERNAL_DEFINITIONS blocks in the
- /// chain. The referenced declarations are deserialized and passed to the
- /// consumer eagerly.
- SmallVector<uint64_t, 16> ExternalDefinitions;
+ /// This contains the data loaded from all EAGERLY_DESERIALIZED_DECLS blocks
+ /// in the chain. The referenced declarations are deserialized and passed to
+ /// the consumer eagerly.
+ SmallVector<uint64_t, 16> EagerlyDeserializedDecls;
/// \brief The IDs of all tentative definitions stored in the chain.
///
/// \brief Declarations encountered that might be external
/// definitions.
///
- /// We keep track of external definitions (as well as tentative
- /// definitions) as we are emitting declarations to the AST
- /// file. The AST file contains a separate record for these external
- /// definitions, which are provided to the AST consumer by the AST
- /// reader. This is behavior is required to properly cope with,
+ /// We keep track of external definitions and other 'interesting' declarations
+ /// as we are emitting declarations to the AST file. The AST file contains a
+ /// separate record for these declarations, which are provided to the AST
+ /// consumer by the AST reader. This is behavior is required to properly cope with,
/// e.g., tentative variable definitions that occur within
/// headers. The declarations themselves are stored as declaration
- /// IDs, since they will be written out to an EXTERNAL_DEFINITIONS
+ /// IDs, since they will be written out to an EAGERLY_DESERIALIZED_DECLS
/// record.
- SmallVector<uint64_t, 16> ExternalDefinitions;
+ SmallVector<uint64_t, 16> EagerlyDeserializedDecls;
/// \brief DeclContexts that have received extensions since their serialized
/// form.
break;
}
- case EXTERNAL_DEFINITIONS:
+ case EAGERLY_DESERIALIZED_DECLS:
for (unsigned I = 0, N = Record.size(); I != N; ++I)
- ExternalDefinitions.push_back(getGlobalDeclID(F, Record[I]));
+ EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I]));
break;
case SPECIAL_TYPES:
if (!Consumer)
return;
- for (unsigned I = 0, N = ExternalDefinitions.size(); I != N; ++I) {
+ for (unsigned I = 0, N = EagerlyDeserializedDecls.size(); I != N; ++I) {
// Force deserialization of this decl, which will cause it to be queued for
// passing to the consumer.
- GetDecl(ExternalDefinitions[I]);
+ GetDecl(EagerlyDeserializedDecls[I]);
}
- ExternalDefinitions.clear();
+ EagerlyDeserializedDecls.clear();
PassInterestingDeclsToConsumer();
}
if (isa<FileScopeAsmDecl>(D) ||
isa<ObjCProtocolDecl>(D) ||
- isa<ObjCImplDecl>(D))
+ isa<ObjCImplDecl>(D) ||
+ isa<ImportDecl>(D))
return true;
if (VarDecl *Var = dyn_cast<VarDecl>(D))
return Var->isFileVarDecl() &&
RECORD(DECL_OFFSET);
RECORD(IDENTIFIER_OFFSET);
RECORD(IDENTIFIER_TABLE);
- RECORD(EXTERNAL_DEFINITIONS);
+ RECORD(EAGERLY_DESERIALIZED_DECLS);
RECORD(SPECIAL_TYPES);
RECORD(STATISTICS);
RECORD(TENTATIVE_DEFINITIONS);
Stream.EmitRecord(SPECIAL_TYPES, SpecialTypes);
// Write the record containing external, unnamed definitions.
- if (!ExternalDefinitions.empty())
- Stream.EmitRecord(EXTERNAL_DEFINITIONS, ExternalDefinitions);
+ if (!EagerlyDeserializedDecls.empty())
+ Stream.EmitRecord(EAGERLY_DESERIALIZED_DECLS, EagerlyDeserializedDecls);
// Write the record containing tentative definitions.
if (!TentativeDefinitions.empty())
// An ObjCMethodDecl is never considered as "required" because its
// implementation container always is.
- // File scoped assembly or obj-c implementation must be seen.
- if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplDecl>(D))
+ // File scoped assembly or obj-c implementation must be seen. ImportDecl is
+ // used by codegen to determine the set of imported modules to search for
+ // inputs for automatic linking.
+ if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplDecl>(D) || isa<ImportDecl>(D))
return true;
return Context.DeclMustBeEmitted(D);
// Flush C++ base specifiers, if there are any.
FlushCXXBaseSpecifiers();
- // Note "external" declarations so that we can add them to a record in the
- // AST file later.
- //
- // FIXME: This should be renamed, the predicate is much more complicated.
+ // Note declarations that should be deserialized eagerly so that we can add
+ // them to a record in the AST file later.
if (isRequiredDecl(D, Context))
- ExternalDefinitions.push_back(ID);
+ EagerlyDeserializedDecls.push_back(ID);
}
--- /dev/null
+int autolink_sub3(void);
--- /dev/null
+@import autolink.sub3;
header "autolink-sub2.h"
link framework "autolink_framework"
}
+
+ explicit module sub3 {
+ header "autolink-sub3.h"
+ link "autolink_from_pch"
+ }
}
module weird_objc {
// RUN: rm -rf %t
-// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -fmodules -F %S/Inputs -I %S/Inputs %s | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm -fno-autolink -o - -fmodules-cache-path=%t -fmodules -F %S/Inputs -I %S/Inputs %s | FileCheck --check-prefix=CHECK-AUTOLINK-DISABLED %s
+// RUN: %clang_cc1 -emit-pch -fmodules-cache-path=%t -fmodules -o %t.pch -I %S/Inputs -x objective-c-header %S/Inputs/autolink-sub3.pch
+// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -fmodules -F %S/Inputs -I %S/Inputs -include-pch %t.pch %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -fno-autolink -o - -fmodules-cache-path=%t -fmodules -F %S/Inputs -I %S/Inputs -include-pch %t.pch %s | FileCheck --check-prefix=CHECK-AUTOLINK-DISABLED %s
@import autolink.sub2;
return no_umbrella_A;
}
+int use_autolink_sub3() {
+ return autolink_sub3();
+}
+
// NOTE: "autolink_sub" is intentionally not linked.
// CHECK: !llvm.module.flags = !{!0, !1, !2, !3, !4}
// CHECK: !4 = metadata !{i32 6, metadata !"Linker Options", metadata ![[AUTOLINK_OPTIONS:[0-9]+]]}
-// CHECK: ![[AUTOLINK_OPTIONS]] = metadata !{metadata ![[AUTOLINK_FRAMEWORK:[0-9]+]], metadata ![[AUTOLINK:[0-9]+]], metadata ![[DEPENDSONMODULE:[0-9]+]], metadata ![[MODULE:[0-9]+]], metadata ![[NOUMBRELLA:[0-9]+]]}
+// CHECK: ![[AUTOLINK_OPTIONS]] = metadata !{metadata ![[AUTOLINK_PCH:[0-9]+]], metadata ![[AUTOLINK_FRAMEWORK:[0-9]+]], metadata ![[AUTOLINK:[0-9]+]], metadata ![[DEPENDSONMODULE:[0-9]+]], metadata ![[MODULE:[0-9]+]], metadata ![[NOUMBRELLA:[0-9]+]]}
+// CHECK: ![[AUTOLINK_PCH]] = metadata !{metadata !"{{(-l|/DEFAULTLIB:)}}autolink_from_pch{{(\.lib)?}}"}
// CHECK: ![[AUTOLINK_FRAMEWORK]] = metadata !{metadata !"-framework", metadata !"autolink_framework"}
// CHECK: ![[AUTOLINK]] = metadata !{metadata !"{{(-l|/DEFAULTLIB:)}}autolink{{(\.lib)?}}"}
// CHECK: ![[DEPENDSONMODULE]] = metadata !{metadata !"-framework", metadata !"DependsOnModule"}