Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
e422fc1d
Commit
e422fc1d
authored
Nov 30, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Simplify mutex usage in compiler code.
parent
e1fdba61
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
114 additions
and
111 deletions
+114
-111
capnp.c++
c++/src/capnp/compiler/capnp.c++
+11
-11
compiler.c++
c++/src/capnp/compiler/compiler.c++
+0
-0
compiler.h
c++/src/capnp/compiler/compiler.h
+14
-9
error-reporter.h
c++/src/capnp/compiler/error-reporter.h
+5
-5
evolution-test.c++
c++/src/capnp/compiler/evolution-test.c++
+5
-5
lexer-test.c++
c++/src/capnp/compiler/lexer-test.c++
+2
-2
lexer.c++
c++/src/capnp/compiler/lexer.c++
+3
-3
lexer.h
c++/src/capnp/compiler/lexer.h
+3
-4
module-loader.c++
c++/src/capnp/compiler/module-loader.c++
+24
-28
module-loader.h
c++/src/capnp/compiler/module-loader.h
+2
-2
node-translator.c++
c++/src/capnp/compiler/node-translator.c++
+6
-6
node-translator.h
c++/src/capnp/compiler/node-translator.h
+9
-9
parser.c++
c++/src/capnp/compiler/parser.c++
+6
-8
parser.h
c++/src/capnp/compiler/parser.h
+3
-3
schema-parser.c++
c++/src/capnp/schema-parser.c++
+11
-11
schema-parser.h
c++/src/capnp/schema-parser.h
+7
-5
errors.capnp.nobuild
c++/src/capnp/testdata/errors.capnp.nobuild
+2
-0
errors.txt
c++/src/capnp/testdata/errors.txt
+1
-0
No files found.
c++/src/capnp/compiler/capnp.c++
View file @
e422fc1d
...
...
@@ -298,7 +298,7 @@ public:
}
private
:
kj
::
Maybe
<
const
Module
&>
loadModule
(
kj
::
StringPtr
file
)
{
kj
::
Maybe
<
Module
&>
loadModule
(
kj
::
StringPtr
file
)
{
size_t
longestPrefix
=
0
;
for
(
auto
&
prefix
:
sourcePrefixes
)
{
...
...
@@ -1218,12 +1218,12 @@ private:
kj
::
ArrayPtr
<
const
char
>
content
)
:
globalReporter
(
globalReporter
),
lineBreaks
(
content
)
{}
void
addError
(
uint32_t
startByte
,
uint32_t
endByte
,
kj
::
StringPtr
message
)
const
override
{
void
addError
(
uint32_t
startByte
,
uint32_t
endByte
,
kj
::
StringPtr
message
)
override
{
globalReporter
.
addError
(
"<stdin>"
,
lineBreaks
.
toSourcePos
(
startByte
),
lineBreaks
.
toSourcePos
(
endByte
),
message
);
}
bool
hadErrors
()
const
override
{
bool
hadErrors
()
override
{
return
globalReporter
.
hadErrors
();
}
...
...
@@ -1234,7 +1234,7 @@ private:
class
ValueResolverGlue
final
:
public
ValueTranslator
::
Resolver
{
public
:
ValueResolverGlue
(
const
SchemaLoader
&
loader
,
const
ErrorReporter
&
errorReporter
)
ValueResolverGlue
(
const
SchemaLoader
&
loader
,
ErrorReporter
&
errorReporter
)
:
loader
(
loader
),
errorReporter
(
errorReporter
)
{}
kj
::
Maybe
<
Schema
>
resolveType
(
uint64_t
id
)
{
...
...
@@ -1266,14 +1266,14 @@ private:
private
:
const
SchemaLoader
&
loader
;
const
ErrorReporter
&
errorReporter
;
ErrorReporter
&
errorReporter
;
};
public
:
// =====================================================================================
void
addError
(
kj
::
StringPtr
file
,
SourcePos
start
,
SourcePos
end
,
kj
::
StringPtr
message
)
const
override
{
kj
::
StringPtr
message
)
override
{
kj
::
String
wholeMessage
;
if
(
end
.
line
==
start
.
line
)
{
if
(
end
.
column
==
start
.
column
)
{
...
...
@@ -1289,11 +1289,11 @@ public:
}
context
.
error
(
wholeMessage
);
__atomic_store_n
(
&
hadErrors_
,
true
,
__ATOMIC_RELAXED
)
;
hadErrors_
=
true
;
}
bool
hadErrors
()
const
override
{
return
__atomic_load_n
(
&
hadErrors_
,
__ATOMIC_RELAXED
)
;
bool
hadErrors
()
override
{
return
hadErrors_
;
}
private
:
...
...
@@ -1326,7 +1326,7 @@ private:
struct
SourceFile
{
uint64_t
id
;
kj
::
StringPtr
name
;
const
Module
*
module
;
Module
*
module
;
};
kj
::
Vector
<
SourceFile
>
sourceFiles
;
...
...
@@ -1337,7 +1337,7 @@ private:
};
kj
::
Vector
<
OutputDirective
>
outputs
;
mutable
bool
hadErrors_
=
false
;
bool
hadErrors_
=
false
;
};
}
// namespace compiler
...
...
c++/src/capnp/compiler/compiler.c++
View file @
e422fc1d
This diff is collapsed.
Click to expand it.
c++/src/capnp/compiler/compiler.h
View file @
e422fc1d
...
...
@@ -34,21 +34,23 @@ namespace compiler {
class
Module
:
public
ErrorReporter
{
public
:
virtual
kj
::
StringPtr
getSourceName
()
const
=
0
;
virtual
kj
::
StringPtr
getSourceName
()
=
0
;
// The name of the module file relative to the source tree. Used to decide where to output
// generated code and to form the `displayName` in the schema.
virtual
Orphan
<
ParsedFile
>
loadContent
(
Orphanage
orphanage
)
const
=
0
;
virtual
Orphan
<
ParsedFile
>
loadContent
(
Orphanage
orphanage
)
=
0
;
// Loads the module content, using the given orphanage to allocate objects if necessary.
virtual
kj
::
Maybe
<
const
Module
&>
importRelative
(
kj
::
StringPtr
importPath
)
const
=
0
;
virtual
kj
::
Maybe
<
Module
&>
importRelative
(
kj
::
StringPtr
importPath
)
=
0
;
// Find another module, relative to this one. Importing the same logical module twice should
// produce the exact same object, comparable by identity. These objects are owned by some
// outside pool that outlives the Compiler instance.
};
class
Compiler
{
class
Compiler
:
private
SchemaLoader
::
LazyLoadCallback
{
// Cross-links separate modules (schema files) and translates them into schema nodes.
//
// This class is thread-safe, hence all its methods are const.
public
:
enum
AnnotationFlag
{
...
...
@@ -71,7 +73,7 @@ public:
~
Compiler
()
noexcept
(
false
);
KJ_DISALLOW_COPY
(
Compiler
);
uint64_t
add
(
const
Module
&
module
)
const
;
uint64_t
add
(
Module
&
module
)
const
;
// Add a module to the Compiler, returning the module's file ID. The ID can then be looked up in
// the `SchemaLoader` returned by `getLoader()`. However, the SchemaLoader may behave as if the
// schema node doesn't exist if any compilation errors occur (reported via the module's
...
...
@@ -85,7 +87,7 @@ public:
// given name. Neither the parent nor the child schema node is actually compiled.
Orphan
<
List
<
schema
::
CodeGeneratorRequest
::
RequestedFile
::
Import
>>
getFileImportTable
(
const
Module
&
module
,
Orphanage
orphanage
)
const
;
getFileImportTable
(
Module
&
module
,
Orphanage
orphanage
)
const
;
// Build the import table for the CodeGeneratorRequest for the given module.
enum
Eagerness
:
uint32_t
{
...
...
@@ -159,11 +161,11 @@ public:
// If this returns and no errors have been reported, then it is guaranteed that the compiled
// nodes can be found in the SchemaLoader returned by `getLoader()`.
const
SchemaLoader
&
getLoader
()
const
;
const
SchemaLoader
&
getLoader
()
const
{
return
loader
;
}
// Get a SchemaLoader backed by this compiler. Schema nodes will be lazily constructed as you
// traverse them using this loader.
void
clearWorkspace
();
void
clearWorkspace
()
const
;
// The compiler builds a lot of temporary tables and data structures while it works. It's
// useful to keep these around if more work is expected (especially if you are using lazy
// compilation and plan to look up Schema nodes that haven't already been seen), but once
...
...
@@ -174,11 +176,14 @@ public:
private
:
class
Impl
;
kj
::
Own
<
Impl
>
impl
;
kj
::
MutexGuarded
<
kj
::
Own
<
Impl
>>
impl
;
SchemaLoader
loader
;
class
CompiledModule
;
class
Node
;
class
Alias
;
void
load
(
const
SchemaLoader
&
loader
,
uint64_t
id
)
const
override
;
};
}
// namespace compiler
...
...
c++/src/capnp/compiler/error-reporter.h
View file @
e422fc1d
...
...
@@ -36,20 +36,20 @@ class ErrorReporter {
// Callback for reporting errors within a particular file.
public
:
virtual
void
addError
(
uint32_t
startByte
,
uint32_t
endByte
,
kj
::
StringPtr
message
)
const
=
0
;
virtual
void
addError
(
uint32_t
startByte
,
uint32_t
endByte
,
kj
::
StringPtr
message
)
=
0
;
// Report an error at the given location in the input text. `startByte` and `endByte` indicate
// the span of text that is erroneous. They may be equal, in which case the parser was only
// able to identify where the error begins, not where it ends.
template
<
typename
T
>
inline
void
addErrorOn
(
T
&&
decl
,
kj
::
StringPtr
message
)
const
{
inline
void
addErrorOn
(
T
&&
decl
,
kj
::
StringPtr
message
)
{
// Works for any `T` that defines `getStartByte()` and `getEndByte()` methods, which many
// of the Cap'n Proto types defined in `grammar.capnp` do.
addError
(
decl
.
getStartByte
(),
decl
.
getEndByte
(),
message
);
}
virtual
bool
hadErrors
()
const
=
0
;
virtual
bool
hadErrors
()
=
0
;
// Return true if any errors have been reported, globally. The main use case for this callback
// is to inhibit the reporting of errors which may have been caused by previous errors, or to
// allow the compiler to bail out entirely if it gets confused and thinks this could be because
...
...
@@ -67,10 +67,10 @@ public:
};
virtual
void
addError
(
kj
::
StringPtr
file
,
SourcePos
start
,
SourcePos
end
,
kj
::
StringPtr
message
)
const
=
0
;
kj
::
StringPtr
message
)
=
0
;
// Report an error at the given location in the given file.
virtual
bool
hadErrors
()
const
=
0
;
virtual
bool
hadErrors
()
=
0
;
// Return true if any errors have been reported, globally. The main use case for this callback
// is to inhibit the reporting of errors which may have been caused by previous errors, or to
// allow the compiler to bail out entirely if it gets confused and thinks this could be because
...
...
c++/src/capnp/compiler/evolution-test.c++
View file @
e422fc1d
...
...
@@ -632,18 +632,18 @@ class ModuleImpl final: public Module {
public
:
explicit
ModuleImpl
(
ParsedFile
::
Reader
content
)
:
content
(
content
)
{}
kj
::
StringPtr
getSourceName
()
const
override
{
return
"evolving-schema.capnp"
;
}
Orphan
<
ParsedFile
>
loadContent
(
Orphanage
orphanage
)
const
override
{
kj
::
StringPtr
getSourceName
()
override
{
return
"evolving-schema.capnp"
;
}
Orphan
<
ParsedFile
>
loadContent
(
Orphanage
orphanage
)
override
{
return
orphanage
.
newOrphanCopy
(
content
);
}
kj
::
Maybe
<
const
Module
&>
importRelative
(
kj
::
StringPtr
importPath
)
const
override
{
kj
::
Maybe
<
Module
&>
importRelative
(
kj
::
StringPtr
importPath
)
override
{
return
nullptr
;
}
void
addError
(
uint32_t
startByte
,
uint32_t
endByte
,
kj
::
StringPtr
message
)
const
override
{
void
addError
(
uint32_t
startByte
,
uint32_t
endByte
,
kj
::
StringPtr
message
)
override
{
KJ_FAIL_ASSERT
(
"Unexpected parse error."
,
startByte
,
endByte
,
message
);
}
bool
hadErrors
()
const
override
{
bool
hadErrors
()
override
{
return
false
;
}
...
...
c++/src/capnp/compiler/lexer-test.c++
View file @
e422fc1d
...
...
@@ -31,11 +31,11 @@ namespace {
class
TestFailingErrorReporter
:
public
ErrorReporter
{
public
:
void
addError
(
uint32_t
startByte
,
uint32_t
endByte
,
kj
::
StringPtr
message
)
const
override
{
void
addError
(
uint32_t
startByte
,
uint32_t
endByte
,
kj
::
StringPtr
message
)
override
{
ADD_FAILURE
()
<<
"Parse failed: ("
<<
startByte
<<
"-"
<<
endByte
<<
") "
<<
message
.
cStr
();
}
bool
hadErrors
()
const
override
{
bool
hadErrors
()
override
{
// Not used by lexer.
return
false
;
}
...
...
c++/src/capnp/compiler/lexer.c++
View file @
e422fc1d
...
...
@@ -31,7 +31,7 @@ namespace compiler {
namespace
p
=
kj
::
parse
;
bool
lex
(
kj
::
ArrayPtr
<
const
char
>
input
,
LexedStatements
::
Builder
result
,
const
ErrorReporter
&
errorReporter
)
{
ErrorReporter
&
errorReporter
)
{
Lexer
lexer
(
Orphanage
::
getForMessageContaining
(
result
),
errorReporter
);
auto
parser
=
p
::
sequence
(
lexer
.
getParsers
().
statementSequence
,
p
::
endOfInput
);
...
...
@@ -53,7 +53,7 @@ bool lex(kj::ArrayPtr<const char> input, LexedStatements::Builder result,
}
bool
lex
(
kj
::
ArrayPtr
<
const
char
>
input
,
LexedTokens
::
Builder
result
,
const
ErrorReporter
&
errorReporter
)
{
ErrorReporter
&
errorReporter
)
{
Lexer
lexer
(
Orphanage
::
getForMessageContaining
(
result
),
errorReporter
);
auto
parser
=
p
::
sequence
(
lexer
.
getParsers
().
tokenSequence
,
p
::
endOfInput
);
...
...
@@ -138,7 +138,7 @@ constexpr auto docComment = p::optional(p::sequence(
}
// namespace
Lexer
::
Lexer
(
Orphanage
orphanageParam
,
const
ErrorReporter
&
errorReporterParam
)
Lexer
::
Lexer
(
Orphanage
orphanageParam
,
ErrorReporter
&
errorReporterParam
)
:
orphanage
(
orphanageParam
)
{
// Note that because passing an lvalue to a parser constructor uses it by-referencee, it's safe
...
...
c++/src/capnp/compiler/lexer.h
View file @
e422fc1d
...
...
@@ -33,9 +33,8 @@ namespace capnp {
namespace
compiler
{
bool
lex
(
kj
::
ArrayPtr
<
const
char
>
input
,
LexedStatements
::
Builder
result
,
const
ErrorReporter
&
errorReporter
);
bool
lex
(
kj
::
ArrayPtr
<
const
char
>
input
,
LexedTokens
::
Builder
result
,
const
ErrorReporter
&
errorReporter
);
ErrorReporter
&
errorReporter
);
bool
lex
(
kj
::
ArrayPtr
<
const
char
>
input
,
LexedTokens
::
Builder
result
,
ErrorReporter
&
errorReporter
);
// Lex the given source code, placing the results in `result`. Returns true if there
// were no errors, false if there were. Even when errors are present, the file may have partial
// content which can be fed into later stages of parsing in order to find more errors.
...
...
@@ -49,7 +48,7 @@ class Lexer {
// into your own parsers.
public
:
Lexer
(
Orphanage
orphanage
,
const
ErrorReporter
&
errorReporter
);
Lexer
(
Orphanage
orphanage
,
ErrorReporter
&
errorReporter
);
// `orphanage` is used to allocate Cap'n Proto message objects in the result. `inputStart` is
// a pointer to the beginning of the input, used to compute byte offsets.
...
...
c++/src/capnp/compiler/module-loader.c++
View file @
e422fc1d
...
...
@@ -198,41 +198,40 @@ kj::String catPath(kj::StringPtr base, kj::StringPtr add) {
class
ModuleLoader
::
Impl
{
public
:
Impl
(
const
GlobalErrorReporter
&
errorReporter
)
:
errorReporter
(
errorReporter
)
{}
Impl
(
GlobalErrorReporter
&
errorReporter
)
:
errorReporter
(
errorReporter
)
{}
void
addImportPath
(
kj
::
String
path
)
{
searchPath
.
add
(
kj
::
heapString
(
kj
::
mv
(
path
)));
}
kj
::
Maybe
<
const
Module
&>
loadModule
(
kj
::
StringPtr
localName
,
kj
::
StringPtr
sourceName
)
const
;
kj
::
Maybe
<
const
Module
&>
loadModuleFromSearchPath
(
kj
::
StringPtr
sourceName
)
const
;
const
GlobalErrorReporter
&
getErrorReporter
()
const
{
return
errorReporter
;
}
kj
::
Maybe
<
Module
&>
loadModule
(
kj
::
StringPtr
localName
,
kj
::
StringPtr
sourceName
)
;
kj
::
Maybe
<
Module
&>
loadModuleFromSearchPath
(
kj
::
StringPtr
sourceName
)
;
GlobalErrorReporter
&
getErrorReporter
()
{
return
errorReporter
;
}
private
:
const
GlobalErrorReporter
&
errorReporter
;
GlobalErrorReporter
&
errorReporter
;
kj
::
Vector
<
kj
::
String
>
searchPath
;
kj
::
MutexGuarded
<
std
::
map
<
kj
::
StringPtr
,
kj
::
Own
<
Module
>>>
modules
;
};
class
ModuleLoader
::
ModuleImpl
final
:
public
Module
{
public
:
ModuleImpl
(
const
ModuleLoader
::
Impl
&
loader
,
kj
::
String
localName
,
kj
::
String
sourceName
)
ModuleImpl
(
ModuleLoader
::
Impl
&
loader
,
kj
::
String
localName
,
kj
::
String
sourceName
)
:
loader
(
loader
),
localName
(
kj
::
mv
(
localName
)),
sourceName
(
kj
::
mv
(
sourceName
))
{}
kj
::
StringPtr
getLocalName
()
const
{
kj
::
StringPtr
getLocalName
()
{
return
localName
;
}
kj
::
StringPtr
getSourceName
()
const
override
{
kj
::
StringPtr
getSourceName
()
override
{
return
sourceName
;
}
Orphan
<
ParsedFile
>
loadContent
(
Orphanage
orphanage
)
const
override
{
Orphan
<
ParsedFile
>
loadContent
(
Orphanage
orphanage
)
override
{
kj
::
Array
<
const
char
>
content
=
mmapForRead
(
localName
);
lineBreaks
.
get
([
&
](
kj
::
SpaceFor
<
LineBreakTable
>&
space
)
{
return
space
.
construct
(
content
);
});
lineBreaks
=
nullptr
;
// In case loadContent() is called multiple times.
lineBreaks
=
lineBreaksSpace
.
construct
(
content
);
MallocMessageBuilder
lexedBuilder
;
auto
statements
=
lexedBuilder
.
initRoot
<
LexedStatements
>
();
...
...
@@ -243,7 +242,7 @@ public:
return
parsed
;
}
kj
::
Maybe
<
const
Module
&>
importRelative
(
kj
::
StringPtr
importPath
)
const
override
{
kj
::
Maybe
<
Module
&>
importRelative
(
kj
::
StringPtr
importPath
)
override
{
if
(
importPath
.
size
()
>
0
&&
importPath
[
0
]
==
'/'
)
{
return
loader
.
loadModuleFromSearchPath
(
importPath
.
slice
(
1
));
}
else
{
...
...
@@ -251,32 +250,31 @@ public:
}
}
void
addError
(
uint32_t
startByte
,
uint32_t
endByte
,
kj
::
StringPtr
message
)
const
override
{
auto
&
lines
=
lineBreaks
.
get
(
[](
kj
::
SpaceFor
<
LineBreakTable
>&
space
)
->
kj
::
Own
<
LineBreakTable
>
{
KJ_FAIL_REQUIRE
(
"Can't report errors until loadContent() is called."
);
});
void
addError
(
uint32_t
startByte
,
uint32_t
endByte
,
kj
::
StringPtr
message
)
override
{
auto
&
lines
=
*
KJ_REQUIRE_NONNULL
(
lineBreaks
,
"Can't report errors until loadContent() is called."
);
loader
.
getErrorReporter
().
addError
(
localName
,
lines
.
toSourcePos
(
startByte
),
lines
.
toSourcePos
(
endByte
),
message
);
}
bool
hadErrors
()
const
override
{
bool
hadErrors
()
override
{
return
loader
.
getErrorReporter
().
hadErrors
();
}
private
:
const
ModuleLoader
::
Impl
&
loader
;
ModuleLoader
::
Impl
&
loader
;
kj
::
String
localName
;
kj
::
String
sourceName
;
kj
::
Lazy
<
LineBreakTable
>
lineBreaks
;
kj
::
SpaceFor
<
LineBreakTable
>
lineBreaksSpace
;
kj
::
Maybe
<
kj
::
Own
<
LineBreakTable
>>
lineBreaks
;
};
// =======================================================================================
kj
::
Maybe
<
const
Module
&>
ModuleLoader
::
Impl
::
loadModule
(
kj
::
StringPtr
localName
,
kj
::
StringPtr
sourceName
)
const
{
kj
::
Maybe
<
Module
&>
ModuleLoader
::
Impl
::
loadModule
(
kj
::
StringPtr
localName
,
kj
::
StringPtr
sourceName
)
{
kj
::
String
canonicalLocalName
=
canonicalizePath
(
localName
);
kj
::
String
canonicalSourceName
=
canonicalizePath
(
sourceName
);
...
...
@@ -300,8 +298,7 @@ kj::Maybe<const Module&> ModuleLoader::Impl::loadModule(
return
result
;
}
kj
::
Maybe
<
const
Module
&>
ModuleLoader
::
Impl
::
loadModuleFromSearchPath
(
kj
::
StringPtr
sourceName
)
const
{
kj
::
Maybe
<
Module
&>
ModuleLoader
::
Impl
::
loadModuleFromSearchPath
(
kj
::
StringPtr
sourceName
)
{
for
(
auto
&
search
:
searchPath
)
{
kj
::
String
candidate
=
kj
::
str
(
search
,
"/"
,
sourceName
);
char
*
end
=
canonicalizePath
(
candidate
.
begin
()
+
(
candidate
[
0
]
==
'/'
));
...
...
@@ -316,14 +313,13 @@ kj::Maybe<const Module&> ModuleLoader::Impl::loadModuleFromSearchPath(
// =======================================================================================
ModuleLoader
::
ModuleLoader
(
const
GlobalErrorReporter
&
errorReporter
)
ModuleLoader
::
ModuleLoader
(
GlobalErrorReporter
&
errorReporter
)
:
impl
(
kj
::
heap
<
Impl
>
(
errorReporter
))
{}
ModuleLoader
::~
ModuleLoader
()
noexcept
(
false
)
{}
void
ModuleLoader
::
addImportPath
(
kj
::
String
path
)
{
impl
->
addImportPath
(
kj
::
mv
(
path
));
}
kj
::
Maybe
<
const
Module
&>
ModuleLoader
::
loadModule
(
kj
::
StringPtr
localName
,
kj
::
StringPtr
sourceName
)
const
{
kj
::
Maybe
<
Module
&>
ModuleLoader
::
loadModule
(
kj
::
StringPtr
localName
,
kj
::
StringPtr
sourceName
)
{
return
impl
->
loadModule
(
localName
,
sourceName
);
}
...
...
c++/src/capnp/compiler/module-loader.h
View file @
e422fc1d
...
...
@@ -35,7 +35,7 @@ namespace compiler {
class
ModuleLoader
{
public
:
explicit
ModuleLoader
(
const
GlobalErrorReporter
&
errorReporter
);
explicit
ModuleLoader
(
GlobalErrorReporter
&
errorReporter
);
// Create a ModuleLoader that reports error messages to the given reporter.
KJ_DISALLOW_COPY
(
ModuleLoader
);
...
...
@@ -45,7 +45,7 @@ public:
void
addImportPath
(
kj
::
String
path
);
// Add a directory to the list of paths that is searched for imports that start with a '/'.
kj
::
Maybe
<
const
Module
&>
loadModule
(
kj
::
StringPtr
localName
,
kj
::
StringPtr
sourceName
)
const
;
kj
::
Maybe
<
Module
&>
loadModule
(
kj
::
StringPtr
localName
,
kj
::
StringPtr
sourceName
)
;
// Tries to load the module with the given filename. `localName` is the path to the file on
// disk (as you'd pass to open(2)), and `sourceName` is the canonical name it should be given
// in the schema (this is used e.g. to decide output file locations). Often, these are the same.
...
...
c++/src/capnp/compiler/node-translator.c++
View file @
e422fc1d
...
...
@@ -524,7 +524,7 @@ private:
// =======================================================================================
NodeTranslator
::
NodeTranslator
(
const
Resolver
&
resolver
,
const
ErrorReporter
&
errorReporter
,
Resolver
&
resolver
,
ErrorReporter
&
errorReporter
,
const
Declaration
::
Reader
&
decl
,
Orphan
<
schema
::
Node
>
wipNodeParam
,
bool
compileAnnotations
)
:
resolver
(
resolver
),
errorReporter
(
errorReporter
),
...
...
@@ -561,12 +561,12 @@ NodeTranslator::NodeSet NodeTranslator::finish() {
class
NodeTranslator
::
DuplicateNameDetector
{
public
:
inline
explicit
DuplicateNameDetector
(
const
ErrorReporter
&
errorReporter
)
inline
explicit
DuplicateNameDetector
(
ErrorReporter
&
errorReporter
)
:
errorReporter
(
errorReporter
)
{}
void
check
(
List
<
Declaration
>::
Reader
nestedDecls
,
Declaration
::
Which
parentKind
);
private
:
const
ErrorReporter
&
errorReporter
;
ErrorReporter
&
errorReporter
;
std
::
map
<
kj
::
StringPtr
,
LocatedText
::
Reader
>
names
;
};
...
...
@@ -757,7 +757,7 @@ void NodeTranslator::compileAnnotation(Declaration::Annotation::Reader decl,
class
NodeTranslator
::
DuplicateOrdinalDetector
{
public
:
DuplicateOrdinalDetector
(
const
ErrorReporter
&
errorReporter
)
:
errorReporter
(
errorReporter
)
{}
DuplicateOrdinalDetector
(
ErrorReporter
&
errorReporter
)
:
errorReporter
(
errorReporter
)
{}
void
check
(
LocatedInteger
::
Reader
ordinal
)
{
if
(
ordinal
.
getValue
()
<
expectedOrdinal
)
{
...
...
@@ -780,7 +780,7 @@ public:
}
private
:
const
ErrorReporter
&
errorReporter
;
ErrorReporter
&
errorReporter
;
uint
expectedOrdinal
=
0
;
kj
::
Maybe
<
LocatedInteger
::
Reader
>
lastOrdinalLocation
;
};
...
...
@@ -842,7 +842,7 @@ public:
private
:
NodeTranslator
&
translator
;
const
ErrorReporter
&
errorReporter
;
ErrorReporter
&
errorReporter
;
StructLayout
layout
;
kj
::
Arena
arena
;
...
...
c++/src/capnp/compiler/node-translator.h
View file @
e422fc1d
...
...
@@ -49,11 +49,11 @@ public:
Declaration
::
Which
kind
;
};
virtual
kj
::
Maybe
<
ResolvedName
>
resolve
(
const
DeclName
::
Reader
&
name
)
const
=
0
;
virtual
kj
::
Maybe
<
ResolvedName
>
resolve
(
const
DeclName
::
Reader
&
name
)
=
0
;
// Look up the given name, relative to this node, and return basic information about the
// target.
virtual
kj
::
Maybe
<
Schema
>
resolveBootstrapSchema
(
uint64_t
id
)
const
=
0
;
virtual
kj
::
Maybe
<
Schema
>
resolveBootstrapSchema
(
uint64_t
id
)
=
0
;
// Get the schema for the given ID. If a schema is returned, it must be safe to traverse its
// dependencies using Schema::getDependency(). A schema that is only at the bootstrap stage
// is acceptable.
...
...
@@ -62,7 +62,7 @@ public:
// traversing other schemas. Returns null if the ID is recognized, but the corresponding
// schema node failed to be built for reasons that were already reported.
virtual
kj
::
Maybe
<
schema
::
Node
::
Reader
>
resolveFinalSchema
(
uint64_t
id
)
const
=
0
;
virtual
kj
::
Maybe
<
schema
::
Node
::
Reader
>
resolveFinalSchema
(
uint64_t
id
)
=
0
;
// Get the final schema for the given ID. A bootstrap schema is not acceptable. A raw
// node reader is returned rather than a Schema object because using a Schema object built
// by the final schema loader could trigger lazy initialization of dependencies which could
...
...
@@ -72,11 +72,11 @@ public:
// traversing other schemas. Returns null if the ID is recognized, but the corresponding
// schema node failed to be built for reasons that were already reported.
virtual
kj
::
Maybe
<
uint64_t
>
resolveImport
(
kj
::
StringPtr
name
)
const
=
0
;
virtual
kj
::
Maybe
<
uint64_t
>
resolveImport
(
kj
::
StringPtr
name
)
=
0
;
// Get the ID of an imported file given the import path.
};
NodeTranslator
(
const
Resolver
&
resolver
,
const
ErrorReporter
&
errorReporter
,
NodeTranslator
(
Resolver
&
resolver
,
ErrorReporter
&
errorReporter
,
const
Declaration
::
Reader
&
decl
,
Orphan
<
schema
::
Node
>
wipNode
,
bool
compileAnnotations
);
// Construct a NodeTranslator to translate the given declaration. The wipNode starts out with
...
...
@@ -107,8 +107,8 @@ public:
// bootstrap node) and return it.
private
:
const
Resolver
&
resolver
;
const
ErrorReporter
&
errorReporter
;
Resolver
&
resolver
;
ErrorReporter
&
errorReporter
;
Orphanage
orphanage
;
bool
compileAnnotations
;
...
...
@@ -195,7 +195,7 @@ public:
virtual
kj
::
Maybe
<
DynamicValue
::
Reader
>
resolveConstant
(
DeclName
::
Reader
name
)
=
0
;
};
ValueTranslator
(
Resolver
&
resolver
,
const
ErrorReporter
&
errorReporter
,
Orphanage
orphanage
)
ValueTranslator
(
Resolver
&
resolver
,
ErrorReporter
&
errorReporter
,
Orphanage
orphanage
)
:
resolver
(
resolver
),
errorReporter
(
errorReporter
),
orphanage
(
orphanage
)
{}
kj
::
Maybe
<
Orphan
<
DynamicValue
>>
compileValue
(
...
...
@@ -203,7 +203,7 @@ public:
private
:
Resolver
&
resolver
;
const
ErrorReporter
&
errorReporter
;
ErrorReporter
&
errorReporter
;
Orphanage
orphanage
;
Orphan
<
DynamicValue
>
compileValueInner
(
ValueExpression
::
Reader
src
,
schema
::
Type
::
Reader
type
);
...
...
c++/src/capnp/compiler/parser.c++
View file @
e422fc1d
...
...
@@ -122,7 +122,7 @@ uint64_t generateMethodParamsId(uint64_t parentId, uint16_t methodOrdinal, bool
}
void
parseFile
(
List
<
Statement
>::
Reader
statements
,
ParsedFile
::
Builder
result
,
const
ErrorReporter
&
errorReporter
)
{
ErrorReporter
&
errorReporter
)
{
CapnpParser
parser
(
Orphanage
::
getForMessageContaining
(
result
),
errorReporter
);
kj
::
Vector
<
Orphan
<
Declaration
>>
decls
(
statements
.
size
());
...
...
@@ -272,7 +272,7 @@ class ParseListItems {
// Transformer that parses all items in the input token sequence list using the given parser.
public
:
constexpr
ParseListItems
(
ItemParser
&&
itemParser
,
const
ErrorReporter
&
errorReporter
)
constexpr
ParseListItems
(
ItemParser
&&
itemParser
,
ErrorReporter
&
errorReporter
)
:
itemParser
(
p
::
sequence
(
kj
::
fwd
<
ItemParser
>
(
itemParser
),
p
::
endOfInput
)),
errorReporter
(
errorReporter
)
{}
...
...
@@ -310,12 +310,11 @@ public:
private
:
decltype
(
p
::
sequence
(
kj
::
instance
<
ItemParser
>
(),
p
::
endOfInput
))
itemParser
;
const
ErrorReporter
&
errorReporter
;
ErrorReporter
&
errorReporter
;
};
template
<
typename
ItemParser
>
constexpr
auto
parenthesizedList
(
ItemParser
&&
itemParser
,
const
ErrorReporter
&
errorReporter
)
->
decltype
(
constexpr
auto
parenthesizedList
(
ItemParser
&&
itemParser
,
ErrorReporter
&
errorReporter
)
->
decltype
(
transform
(
rawParenthesizedList
,
ParseListItems
<
ItemParser
>
(
kj
::
fwd
<
ItemParser
>
(
itemParser
),
errorReporter
)))
{
return
transform
(
rawParenthesizedList
,
ParseListItems
<
ItemParser
>
(
...
...
@@ -323,8 +322,7 @@ constexpr auto parenthesizedList(ItemParser&& itemParser,
}
template
<
typename
ItemParser
>
constexpr
auto
bracketedList
(
ItemParser
&&
itemParser
,
const
ErrorReporter
&
errorReporter
)
->
decltype
(
constexpr
auto
bracketedList
(
ItemParser
&&
itemParser
,
ErrorReporter
&
errorReporter
)
->
decltype
(
transform
(
rawBracketedList
,
ParseListItems
<
ItemParser
>
(
kj
::
fwd
<
ItemParser
>
(
itemParser
),
errorReporter
)))
{
return
transform
(
rawBracketedList
,
ParseListItems
<
ItemParser
>
(
...
...
@@ -384,7 +382,7 @@ void initLocation(kj::parse::Span<List<Token>::Reader::Iterator> location,
// =======================================================================================
CapnpParser
::
CapnpParser
(
Orphanage
orphanageParam
,
const
ErrorReporter
&
errorReporterParam
)
CapnpParser
::
CapnpParser
(
Orphanage
orphanageParam
,
ErrorReporter
&
errorReporterParam
)
:
orphanage
(
orphanageParam
),
errorReporter
(
errorReporterParam
)
{
parsers
.
declName
=
arena
.
copy
(
p
::
transformWithLocation
(
p
::
sequence
(
...
...
c++/src/capnp/compiler/parser.h
View file @
e422fc1d
...
...
@@ -34,7 +34,7 @@ namespace capnp {
namespace
compiler
{
void
parseFile
(
List
<
Statement
>::
Reader
statements
,
ParsedFile
::
Builder
result
,
const
ErrorReporter
&
errorReporter
);
ErrorReporter
&
errorReporter
);
// Parse a list of statements to build a ParsedFile.
//
// If any errors are reported, then the output is not usable. However, it may be passed on through
...
...
@@ -59,7 +59,7 @@ class CapnpParser {
// them into your own parsers.
public
:
CapnpParser
(
Orphanage
orphanage
,
const
ErrorReporter
&
errorReporter
);
CapnpParser
(
Orphanage
orphanage
,
ErrorReporter
&
errorReporter
);
// `orphanage` is used to allocate Cap'n Proto message objects in the result. `inputStart` is
// a pointer to the beginning of the input, used to compute byte offsets.
...
...
@@ -141,7 +141,7 @@ public:
private
:
Orphanage
orphanage
;
const
ErrorReporter
&
errorReporter
;
ErrorReporter
&
errorReporter
;
kj
::
Arena
arena
;
Parsers
parsers
;
};
...
...
c++/src/capnp/schema-parser.c++
View file @
e422fc1d
...
...
@@ -72,11 +72,11 @@ public:
ModuleImpl
(
const
SchemaParser
&
parser
,
kj
::
Own
<
const
SchemaFile
>&&
file
)
:
parser
(
parser
),
file
(
kj
::
mv
(
file
))
{}
kj
::
StringPtr
getSourceName
()
const
override
{
kj
::
StringPtr
getSourceName
()
override
{
return
file
->
getDisplayName
();
}
Orphan
<
compiler
::
ParsedFile
>
loadContent
(
Orphanage
orphanage
)
const
override
{
Orphan
<
compiler
::
ParsedFile
>
loadContent
(
Orphanage
orphanage
)
override
{
kj
::
Array
<
const
char
>
content
=
file
->
readContent
();
lineBreaks
.
get
([
&
](
kj
::
SpaceFor
<
kj
::
Vector
<
uint
>>&
space
)
{
...
...
@@ -99,7 +99,7 @@ public:
return
parsed
;
}
kj
::
Maybe
<
const
Module
&>
importRelative
(
kj
::
StringPtr
importPath
)
const
override
{
kj
::
Maybe
<
Module
&>
importRelative
(
kj
::
StringPtr
importPath
)
override
{
KJ_IF_MAYBE
(
importedFile
,
file
->
import
(
importPath
))
{
return
parser
.
getModuleImpl
(
kj
::
mv
(
*
importedFile
));
}
else
{
...
...
@@ -107,7 +107,7 @@ public:
}
}
void
addError
(
uint32_t
startByte
,
uint32_t
endByte
,
kj
::
StringPtr
message
)
const
override
{
void
addError
(
uint32_t
startByte
,
uint32_t
endByte
,
kj
::
StringPtr
message
)
override
{
auto
&
lines
=
lineBreaks
.
get
(
[](
kj
::
SpaceFor
<
kj
::
Vector
<
uint
>>&
space
)
{
KJ_FAIL_REQUIRE
(
"Can't report errors until loadContent() is called."
);
...
...
@@ -129,7 +129,7 @@ public:
__atomic_store_n
(
&
parser
.
hadErrors
,
true
,
__ATOMIC_RELAXED
);
}
bool
hadErrors
()
const
override
{
bool
hadErrors
()
override
{
return
__atomic_load_n
(
&
parser
.
hadErrors
,
__ATOMIC_RELAXED
);
}
...
...
@@ -162,7 +162,7 @@ struct SchemaFileEq {
struct
SchemaParser
::
Impl
{
typedef
std
::
unordered_map
<
const
SchemaFile
*
,
kj
::
Own
<
const
ModuleImpl
>
,
SchemaFileHash
,
SchemaFileEq
>
FileMap
;
const
SchemaFile
*
,
kj
::
Own
<
ModuleImpl
>
,
SchemaFileHash
,
SchemaFileEq
>
FileMap
;
kj
::
MutexGuarded
<
FileMap
>
fileMap
;
compiler
::
Compiler
compiler
;
};
...
...
@@ -172,11 +172,11 @@ SchemaParser::~SchemaParser() noexcept(false) {}
ParsedSchema
SchemaParser
::
parseDiskFile
(
kj
::
StringPtr
displayName
,
kj
::
StringPtr
diskPath
,
kj
::
ArrayPtr
<
const
kj
::
StringPtr
>
importPath
)
{
kj
::
ArrayPtr
<
const
kj
::
StringPtr
>
importPath
)
const
{
return
parseFile
(
SchemaFile
::
newDiskFile
(
displayName
,
diskPath
,
importPath
));
}
ParsedSchema
SchemaParser
::
parseFile
(
kj
::
Own
<
SchemaFile
>&&
file
)
{
ParsedSchema
SchemaParser
::
parseFile
(
kj
::
Own
<
SchemaFile
>&&
file
)
const
{
KJ_DEFER
(
impl
->
compiler
.
clearWorkspace
());
uint64_t
id
=
impl
->
compiler
.
add
(
getModuleImpl
(
kj
::
mv
(
file
)));
impl
->
compiler
.
eagerlyCompile
(
id
,
...
...
@@ -185,7 +185,7 @@ ParsedSchema SchemaParser::parseFile(kj::Own<SchemaFile>&& file) {
return
ParsedSchema
(
impl
->
compiler
.
getLoader
().
get
(
id
),
*
this
);
}
const
SchemaParser
::
ModuleImpl
&
SchemaParser
::
getModuleImpl
(
kj
::
Own
<
SchemaFile
>&&
file
)
const
{
SchemaParser
::
ModuleImpl
&
SchemaParser
::
getModuleImpl
(
kj
::
Own
<
SchemaFile
>&&
file
)
const
{
auto
lock
=
impl
->
fileMap
.
lockExclusive
();
auto
insertResult
=
lock
->
insert
(
std
::
make_pair
(
file
.
get
(),
kj
::
Own
<
ModuleImpl
>
()));
...
...
@@ -196,14 +196,14 @@ const SchemaParser::ModuleImpl& SchemaParser::getModuleImpl(kj::Own<SchemaFile>&
return
*
insertResult
.
first
->
second
;
}
kj
::
Maybe
<
ParsedSchema
>
ParsedSchema
::
findNested
(
kj
::
StringPtr
name
)
{
kj
::
Maybe
<
ParsedSchema
>
ParsedSchema
::
findNested
(
kj
::
StringPtr
name
)
const
{
return
parser
->
impl
->
compiler
.
lookup
(
getProto
().
getId
(),
name
).
map
(
[
this
](
uint64_t
childId
)
{
return
ParsedSchema
(
parser
->
impl
->
compiler
.
getLoader
().
get
(
childId
),
*
parser
);
});
}
ParsedSchema
ParsedSchema
::
getNested
(
kj
::
StringPtr
nestedName
)
{
ParsedSchema
ParsedSchema
::
getNested
(
kj
::
StringPtr
nestedName
)
const
{
KJ_IF_MAYBE
(
nested
,
findNested
(
nestedName
))
{
return
*
nested
;
}
else
{
...
...
c++/src/capnp/schema-parser.h
View file @
e422fc1d
...
...
@@ -34,13 +34,15 @@ class SchemaFile;
class
SchemaParser
{
// Parses `.capnp` files to produce `Schema` objects.
//
// This class is thread-safe, hence all its methods are const.
public
:
SchemaParser
();
~
SchemaParser
()
noexcept
(
false
);
ParsedSchema
parseDiskFile
(
kj
::
StringPtr
displayName
,
kj
::
StringPtr
diskPath
,
kj
::
ArrayPtr
<
const
kj
::
StringPtr
>
importPath
);
kj
::
ArrayPtr
<
const
kj
::
StringPtr
>
importPath
)
const
;
// Parse a file located on disk. Throws an exception if the file dosen't exist.
//
// Parameters:
...
...
@@ -61,7 +63,7 @@ public:
// anything in the imported file -- only the imported types which are actually used are
// "dependencies".
ParsedSchema
parseFile
(
kj
::
Own
<
SchemaFile
>&&
file
);
ParsedSchema
parseFile
(
kj
::
Own
<
SchemaFile
>&&
file
)
const
;
// Advanced interface for parsing a file that may or may not be located in any global namespace.
// Most users will prefer `parseDiskFile()`.
//
...
...
@@ -79,7 +81,7 @@ private:
kj
::
Own
<
Impl
>
impl
;
mutable
bool
hadErrors
=
false
;
const
ModuleImpl
&
getModuleImpl
(
kj
::
Own
<
SchemaFile
>&&
file
)
const
;
ModuleImpl
&
getModuleImpl
(
kj
::
Own
<
SchemaFile
>&&
file
)
const
;
friend
class
ParsedSchema
;
};
...
...
@@ -91,11 +93,11 @@ class ParsedSchema: public Schema {
public
:
inline
ParsedSchema
()
:
parser
(
nullptr
)
{}
kj
::
Maybe
<
ParsedSchema
>
findNested
(
kj
::
StringPtr
name
);
kj
::
Maybe
<
ParsedSchema
>
findNested
(
kj
::
StringPtr
name
)
const
;
// Gets the nested node with the given name, or returns null if there is no such nested
// declaration.
ParsedSchema
getNested
(
kj
::
StringPtr
name
);
ParsedSchema
getNested
(
kj
::
StringPtr
name
)
const
;
// Gets the nested node with the given name, or throws an exception if there is no such nested
// declaration.
...
...
c++/src/capnp/testdata/errors.capnp.nobuild
View file @
e422fc1d
...
...
@@ -137,3 +137,5 @@ enum DupEnumerants {
dupNumber1 @2;
dupNumber2 @2;
}
const recursive: UInt32 = .recursive;
c++/src/capnp/testdata/errors.txt
View file @
e422fc1d
...
...
@@ -48,3 +48,4 @@ file:136:3-10: error: 'dupName' is already defined in this scope.
file:135:3-10: error: 'dupName' previously defined here.
file:138:15-16: error: Duplicate ordinal number.
file:137:15-16: error: Ordinal @2 originally used here.
file:141:7-16: error: Declaration recursively depends on itself.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment