Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

[Import as member] Module attribute swift_infer_import_as_member #11

Merged
merged 4 commits into from
Apr 1, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions include/clang/APINotes/APINotesManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ class APINotesManager {

/// Find the API notes reader that corresponds to the given source location.
APINotesReader *findAPINotes(SourceLocation Loc);

APINotesReader *getCurrentModuleReader() {
return CurrentModuleReader.get();
}
};

} // end namespace api_notes
Expand Down
3 changes: 3 additions & 0 deletions include/clang/APINotes/APINotesReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ class APINotesReader {
/// notes.
StringRef getModuleName() const;

/// Retrieve the module options
ModuleOptions getModuleOptions() const;

/// Look for information regarding the given Objective-C class.
///
/// \param name The name of the class we're looking for.
Expand Down
3 changes: 3 additions & 0 deletions include/clang/APINotes/APINotesWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ class APINotesWriter {
/// \param name The name of this typedef.
/// \param info Information about this typedef.
void addTypedef(StringRef name, const TypedefInfo &info);

/// Add module options
void addModuleOptions(ModuleOptions opts);
};

} // end namespace api_notes
Expand Down
5 changes: 5 additions & 0 deletions include/clang/APINotes/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,11 @@ class TypedefInfo : public CommonTypeInfo {
TypedefInfo() : CommonTypeInfo() { }
};

/// Descripts a series of options for a module
struct ModuleOptions {
bool SwiftInferImportAsMember;
};

} // end namespace api_notes
} // end namespace clang

Expand Down
3 changes: 3 additions & 0 deletions include/clang/Basic/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ class Module {
/// \brief Whether this is an inferred submodule (module * { ... }).
unsigned IsInferred : 1;

/// \brief Whether this is a module who has its swift_names inferred.
unsigned IsSwiftInferImportAsMember : 1;

/// \brief Whether we should infer submodules for this module based on
/// the headers.
///
Expand Down
3 changes: 3 additions & 0 deletions include/clang/Lex/ModuleMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ class ModuleMap {

/// \brief Whether this is an exhaustive set of configuration macros.
unsigned IsExhaustive : 1;

/// \brief Whether this is a module who has its swift_names inferred.
unsigned IsSwiftInferImportAsMember : 1;
};

/// \brief A directory for which framework modules can be inferred.
Expand Down
10 changes: 8 additions & 2 deletions lib/APINotes/APINotesFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const uint16_t VERSION_MAJOR = 0;
/// API notes file minor version number.
///
/// When the format changes IN ANY WAY, this number should be incremented.
const uint16_t VERSION_MINOR = 10; // enum constants
const uint16_t VERSION_MINOR = 11; // SwiftInferImportAsMember

using IdentifierID = Fixnum<31>;
using IdentifierIDField = BCVBR<16>;
Expand Down Expand Up @@ -104,7 +104,8 @@ namespace control_block {
// VERSION_MAJOR.
enum {
METADATA = 1,
MODULE_NAME = 2
MODULE_NAME = 2,
MODULE_OPTIONS = 3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please bump the minor version number.

};

using MetadataLayout = BCRecordLayout<
Expand All @@ -117,6 +118,11 @@ namespace control_block {
MODULE_NAME,
BCBlob // Module name
>;

using ModuleOptionsLayout = BCRecordLayout<
MODULE_OPTIONS,
BCFixed<1> // SwiftInferImportAsMember
>;
}

namespace identifier_block {
Expand Down
11 changes: 11 additions & 0 deletions lib/APINotes/APINotesReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,9 @@ class APINotesReader::Implementation {
/// The name of the module that we read from the control block.
std::string ModuleName;

/// Various options and attributes for the module
ModuleOptions ModuleOpts;

using SerializedIdentifierTable =
llvm::OnDiskIterableChainedHashTable<IdentifierTableInfo>;

Expand Down Expand Up @@ -735,6 +738,10 @@ bool APINotesReader::Implementation::readControlBlock(
ModuleName = blobData.str();
break;

case control_block::MODULE_OPTIONS:
ModuleOpts.SwiftInferImportAsMember = (scratch.front() & 1) != 0;
break;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing "break;"? Also, I'd feel a whole lot better if this were explicit:

moduleOptions.SwiftInferImportAsMember = (scratch.front() & 1) != 0

default:
// Unknown metadata record, possibly for use by a future version of the
// module format.
Expand Down Expand Up @@ -1440,6 +1447,10 @@ StringRef APINotesReader::getModuleName() const {
return Impl.ModuleName;
}

ModuleOptions APINotesReader::getModuleOptions() const {
return Impl.ModuleOpts;
}

auto APINotesReader::lookupObjCClass(StringRef name)
-> Optional<std::pair<ContextID, ObjCContextInfo>> {
if (!Impl.ObjCContextTable)
Expand Down
12 changes: 12 additions & 0 deletions lib/APINotes/APINotesWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class APINotesWriter::Implementation {
/// The name of the module
std::string ModuleName;

bool SwiftInferImportAsMember = false;

/// Information about Objective-C contexts (classes or protocols).
///
/// Indexed by the identifier ID and a bit indication whether we're looking
Expand Down Expand Up @@ -214,6 +216,11 @@ void APINotesWriter::Implementation::writeControlBlock(

control_block::ModuleNameLayout moduleName(writer);
moduleName.emit(ScratchRecord, ModuleName);

if (SwiftInferImportAsMember) {
control_block::ModuleOptionsLayout moduleOptions(writer);
moduleOptions.emit(ScratchRecord, SwiftInferImportAsMember);
}
}

namespace {
Expand Down Expand Up @@ -1091,3 +1098,8 @@ void APINotesWriter::addTypedef(llvm::StringRef name, const TypedefInfo &info) {
assert(!Impl.Typedefs.count(typedefID));
Impl.Typedefs[typedefID] = info;
}

void APINotesWriter::addModuleOptions(ModuleOptions opts) {
Impl.SwiftInferImportAsMember = opts.SwiftInferImportAsMember;
}

11 changes: 11 additions & 0 deletions lib/APINotes/APINotesYAMLCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@ namespace {
TagsSeq Tags;
TypedefsSeq Typedefs;

llvm::Optional<bool> SwiftInferImportAsMember;

LLVM_ATTRIBUTE_DEPRECATED(
void dump() LLVM_ATTRIBUTE_USED,
"only for use within the debugger");
Expand Down Expand Up @@ -416,6 +418,7 @@ namespace llvm {
io.mapRequired("Name", m.Name);
io.mapOptional("Availability", m.Availability.Mode);
io.mapOptional("AvailabilityMsg", m.Availability.Msg);
io.mapOptional("SwiftInferImportAsMember", m.SwiftInferImportAsMember);
io.mapOptional("Classes", m.Classes);
io.mapOptional("Protocols", m.Protocols);
io.mapOptional("Functions", m.Functions);
Expand Down Expand Up @@ -771,6 +774,9 @@ namespace {
Writer->addTypedef(t.Name, typedefInfo);
}

if (TheModule.SwiftInferImportAsMember)
Writer->addModuleOptions({true});

if (!ErrorOccured)
Writer->writeToStream(OS);

Expand Down Expand Up @@ -1032,6 +1038,11 @@ bool api_notes::decompileAPINotes(std::unique_ptr<llvm::MemoryBuffer> input,
// Set module name.
module.Name = reader->getModuleName();

// Set module options
auto opts = reader->getModuleOptions();
if (opts.SwiftInferImportAsMember)
module.SwiftInferImportAsMember = true;

// Sort classes.
std::sort(module.Classes.begin(), module.Classes.end(),
[](const Class &lhs, const Class &rhs) -> bool {
Expand Down
2 changes: 2 additions & 0 deletions lib/Basic/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@ void Module::print(raw_ostream &OS, unsigned Indent) const {
OS << " [system]";
if (IsExternC)
OS << " [extern_c]";
if (IsSwiftInferImportAsMember)
OS << " [swift_infer_import_as_member]";
}

OS << " {\n";
Expand Down
16 changes: 14 additions & 2 deletions lib/Frontend/CompilerInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//

#include "clang/Frontend/CompilerInstance.h"
#include "clang/APINotes/APINotesReader.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
Expand Down Expand Up @@ -533,10 +534,21 @@ void CompilerInstance::createSema(TranslationUnitKind TUKind,
TUKind, CompletionConsumer));

// If we're building a module, notify the API notes manager.
if (!getLangOpts().CurrentModule.empty()) {
StringRef currentModuleName = getLangOpts().CurrentModule;
if (!currentModuleName.empty()) {
(void)TheSema->APINotes.loadCurrentModuleAPINotes(
getLangOpts().CurrentModule,
currentModuleName,
getAPINotesOpts().ModuleSearchPaths);
// Check for any attributes we should add to the module
if (auto curReader = TheSema->APINotes.getCurrentModuleReader()) {
auto currentModule = getPreprocessor().getCurrentModule();
assert(currentModule && "how can we have a reader for it?");

// swift_infer_import_as_member
if (curReader->getModuleOptions().SwiftInferImportAsMember) {
currentModule->IsSwiftInferImportAsMember = true;
}
}
}
}

Expand Down
9 changes: 8 additions & 1 deletion lib/Lex/ModuleMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1306,7 +1306,9 @@ namespace {
/// \brief The 'extern_c' attribute.
AT_extern_c,
/// \brief The 'exhaustive' attribute.
AT_exhaustive
AT_exhaustive,
// \brief The 'swift_infer_import_as_member' attribute.
AT_swift_infer_import_as_member,
};
}

Expand Down Expand Up @@ -2379,6 +2381,7 @@ bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
.Case("exhaustive", AT_exhaustive)
.Case("extern_c", AT_extern_c)
.Case("system", AT_system)
.Case("swift_infer_import_as_member", AT_swift_infer_import_as_member)
.Default(AT_unknown);
switch (Attribute) {
case AT_unknown:
Expand All @@ -2394,6 +2397,10 @@ bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
Attrs.IsExternC = true;
break;

case AT_swift_infer_import_as_member:
Attrs.IsSwiftInferImportAsMember = true;
break;

case AT_exhaustive:
Attrs.IsExhaustive = true;
break;
Expand Down
1 change: 1 addition & 0 deletions test/APINotes/Inputs/Headers/APINotes.apinotes
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Name: HeaderLib
SwiftInferImportAsMember: true
Functions:
- Name: custom_realloc
NullabilityOfRet: N
Expand Down
1 change: 1 addition & 0 deletions test/APINotes/Inputs/roundtrip.apinotes
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Name: AppKit
Availability: available
AvailabilityMsg: ''
SwiftInferImportAsMember: true
Classes:
- Name: NSCell
Availability: available
Expand Down
2 changes: 2 additions & 0 deletions test/Modules/Inputs/swift_name/module.modulemap
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module SwiftNameInferred [swift_infer_import_as_member] {
}
6 changes: 6 additions & 0 deletions test/Modules/infer_swift_name.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/swift_name %s -verify
// REQUIRES: shell

@import SwiftNameInferred; // ok
@import SwiftName; // expected-error{{module 'SwiftName' not found}}