Implement SE-0077: precedence group declarations.

What I've implemented here deviates from the current proposal text
in the following ways:

- I had to introduce a FunctionArrowPrecedence to capture the parsing
  of -> in expression contexts.

- I found it convenient to continue to model the assignment property
  explicitly.

- The comparison and casting operators have historically been
  non-associative; I have chosen to preserve that, since I don't
  think this proposal intended to change it.

- This uses the precedence group names and higherThan/lowerThan
  as agreed in discussion.
This commit is contained in:
John McCall
2016-07-26 00:26:15 -07:00
parent 0a8c6ba190
commit c8c41b385c
101 changed files with 2082 additions and 995 deletions

View File

@@ -507,6 +507,9 @@ bool ModuleFile::readIndexBlock(llvm::BitstreamCursor &cursor) {
case index_block::OPERATORS:
OperatorDecls = readDeclTable(scratch, blobData);
break;
case index_block::PRECEDENCE_GROUPS:
PrecedenceGroupDecls = readDeclTable(scratch, blobData);
break;
case index_block::EXTENSIONS:
ExtensionDecls = readDeclTable(scratch, blobData);
break;
@@ -1205,6 +1208,21 @@ OperatorDecl *ModuleFile::lookupOperator(Identifier name, DeclKind fixity) {
return nullptr;
}
PrecedenceGroupDecl *ModuleFile::lookupPrecedenceGroup(Identifier name) {
PrettyModuleFileDeserialization stackEntry(*this);
if (!PrecedenceGroupDecls)
return nullptr;
auto iter = PrecedenceGroupDecls->find(name);
if (iter == PrecedenceGroupDecls->end())
return nullptr;
auto data = *iter;
assert(data.size() == 1);
return cast<PrecedenceGroupDecl>(getDecl(data[0].second));
}
void ModuleFile::getImportedModules(
SmallVectorImpl<Module::ImportedModule> &results,
Module::ImportFilter filter) {
@@ -1472,6 +1490,13 @@ ModuleFile::collectLinkLibraries(Module::LinkLibraryCallback callback) const {
void ModuleFile::getTopLevelDecls(SmallVectorImpl<Decl *> &results) {
PrettyModuleFileDeserialization stackEntry(*this);
if (PrecedenceGroupDecls) {
for (auto entry : PrecedenceGroupDecls->data()) {
for (auto item : entry)
results.push_back(getDecl(item.second));
}
}
if (OperatorDecls) {
for (auto entry : OperatorDecls->data()) {
for (auto item : entry)