Commit Graph

21 Commits

Author SHA1 Message Date
zoecarver
b280d26a7b [cxx-interop] Fix class template instantiation.
Lazily instantiate class template members. This means we no longer
reject some programs that clang accepts, such as the following:

```
template<class T> struct Foo { void fail(T value) { value.fail(); } };
using Bar = Foo<int>;
```

The above program will not error so long as `Bar::fail` isn't called.
(Previously, we'd fail to import `Bar`.)
2021-02-24 11:25:45 -08:00
Slava Pestov
c0aa20298b IRGen: Only emit PragmaCommentDecls if building for Windows, or LTO is enabled
clang::DeclContext::decls_begin() deserializes all the pre-compiled headers
imported into the current translation unit, which is expensive.

Workaround this by disabling the emission of PragmaCommentDecls unless we're
building for a Windows target, or LTO is enabled.

A better fix would be to serialize a separate index for PragmaCommentDecls
so that they can be deserialized without deserializing everything else.
I filed rdar://problem/74036099 to track the longer-term fix.

Fixes rdar://problem/73951264.
2021-02-05 15:34:39 -05:00
scentini
0b3990c141 [cxx-interop] Generate IR for decls called from members (#35056)
Currently the following code doesn't work when `callConstructor()` is called from Swift:
```cc
inline int increment(int value) {
  return value + 1;
}

struct Incrementor {
  int incrementee;
  Incrementor(int value) : incrementee(increment(value)) {}
}

int callConstructor(int value) {
  return Incrementor(value).incrementee;
}
```

The issue is that we don't generate `IR` for the `increment()` function when it's only called from a constructor or a method.
Swift is aware of the existence of `increment()` and we see it in `IR` as `declare incrementEi`, however, as we don't to emit a definition, we get the following error:
```
Incrementor::Incrementor(int): error: undefined reference to 'increment(int)'
```

This PR fixes this by visiting constructors and methods in `IRGen` and calling `HandleTopLevelDecl()` with all used declarations, which results in emitting definitions for the used declarations.

Co-authored-by: Marcel Hlopko <hlopko@google.com>
2021-01-21 10:16:25 +01:00
3405691582
38dd7d8192 [IRGen] Fix asserting local extern declarations.
emitClangDecl interacts with clang and LLVM to achieve C interop. On the
LLVM side, CodeGenModule::EmitGlobal asserts if the decl eventually
passed to it is not a "file scoped" via VarDecl::isFileVarDecl.

LLVM currently asserts on local extern variables in C headers passed to
Swift when the definition exists outside that header. To fix this, we
need to ensure that we are only passing Decls that do not trip the
assertion but not unduly limit local extern variables when the
corresponding definition exists inside that header.

We can do that fairly simply by checking for isFileVarDecl just before
we hand-off to clang. When the definition for the local extern variable
exists inside the header, isFileVarDecl is true, and if it exists
elsewhere, it is false. This matches up with the assert expectation on
the LLVM side exactly.

This indirectly addresses #28968, since that contains the only part of
the Swift stdlib that uses a local extern variable, but any header that
is used with Swift that contains a local extern variable will cause the
compiler to assert when built with assertions enabled.
2020-09-02 00:49:39 -04:00
Martin Boehme
6bf0f26ecd Emit /DEFAULTLIB directive for #pragma comment(lib, ...) in a C module.
This is important, for example, for linking correctly to the C++
standard library on Windows, which uses `#pragma comment(lib, ...)` in
its headers to specify the correct library to link against.
2020-05-20 15:28:12 +02:00
martinboehme
0e75f374d4 Merge branch 'master' into optimize-emit-clang-decl 2020-04-24 17:33:38 +02:00
Martin Boehme
cd7f205ade [IRGen] Check as early as possible for Clang decls we've seen before.
Previously, we were only doing this after the fast-path code that
handles decls without any executable code. This meant, however, that we
were potentially processing these decls multiple times. This is
definitely inefficient; it may even be a correctness issue, depending on
what amount of checking `HandleTopLevelDecl` does to see if it has
processed a particular decl before (which I'm not sure about either
way).
2020-04-24 17:19:19 +02:00
Martin Boehme
d98f8d3a3d Also emit inline functions that are used in variable initializers. 2020-04-17 12:53:06 +02:00
Martin Boehme
6a5722058b Respond to review comment by @rjmccall.
Reinstate fast path where declaration is not a ValueDecl.
2020-04-16 10:52:08 +02:00
Martin Boehme
839c4e05ad Bug fix: Emit code for C++ inline function called from another inline function.
Adds a test that fails without the fix.

The fix consists simply of removing a return statement; as a result, we
now always emit code for functions referenced from the function we are
currently emitting.

Previously, this was not done for externally visible functions. This
goes all the way back to when `GenClangDecl.cpp` was originally introduced here:

ee22004b84

I speculate that the reason for doing this was that in C and Objective-C, we
can assume that an externally visible function will be provided by some
`.o` file we're linking against (though I'm not sure if this is in fact
true for C99 inline functions). At any rate, this assumption is no longer true
for C++ inline functions.
2020-04-15 09:18:22 +02:00
Arnold Schwaighofer
9ddf115b0a IRGen: Don't try to emit non-global variables of imported inline c functions
The previous check would fail because isExternallyVisible() is false for local
static variables with internal linkage.

rdar://29937443
2017-01-18 11:05:20 -08:00
practicalswift
6d1ae2a39c [gardening] 2016 → 2017 2017-01-06 16:41:22 +01:00
practicalswift
797b80765f [gardening] Use the correct base URL (https://swift.org) in references to the Swift website
Remove all references to the old non-TLS enabled base URL (http://swift.org)
2016-11-20 17:36:03 +01:00
John McCall
79c83c7303 Teach IRGen to tell Clang to emit lazy definitions on demand.
Previously, we had hacks in place to eagerly emit everything in
the global ExternalDefinitions list.  These can now be removed,
at least at the IRGen layer.
2016-05-18 22:48:45 -07:00
Michael Gottesman
0ff76575aa Respond to upstream change in clang r253949. 2016-02-06 11:22:25 -08:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
Arnold Schwaighofer
15ff698409 IRGen: Give ClangCodeGen a chance to emit its translation unit's global state
We need this because that global state includes tables like llvm[.compiler].used
which would otherwise be sorely missed.

This fixes an issue of the clang importer that would cause us to fail whenever
we imported a function (say it is marked as static inline) that performs an
objective-c method call and we optimize the code. The optimizer would not see
the objective-c selector global variable (which is marked private) as being
"used by unkown i.e the objc runtime" and would rightly assume it could
propagate the value of the global variable's initializer value as a constant to
loads of the global variable.

Now we call the ClangCodeGenerators translation unit finalization code which
will emit these tables and other module flags. We need to take care that we
merge those datastrutures with datastructures that we emit from swift's IRGen.

rdar://21115194

Swift SVN r29176
2015-05-31 00:01:29 +00:00
Jordan Rose
f4a1841218 [IRGen] Properly track whether we've emitted an imported static function.
...by using the canonical decl in all cases, i.e. "the declaration meant
for when you want to unique things".

rdar://problem/19480333

Swift SVN r24950
2015-02-04 08:10:52 +00:00
Jordan Rose
4fae1f664f [IRGen] Remove the AST walk that looks for local type decls.
Per the previous commit we are no longer using this. Minor save in
simplicity and maybe a bit of compilation time as well.

In the long run IRGen probably shouldn't be pulling information from the
AST at all; the SILModule should be able to tell it what types it needs
to emit information for. But this is still an improvement for now.

No functionality change (that was the previous commit).

Swift SVN r24840
2015-01-30 03:54:08 +00:00
Jordan Rose
06f283f310 [IRGen] Always use the definition of a static inline C function.
...rather than whatever declaration happened to be referenced by a
DeclRefExpr in another function's body.

rdar://problem/18448699

Swift SVN r23877
2014-12-12 03:14:09 +00:00
Jordan Rose
ee22004b84 [IRGen] Walk inlineable Clang functions and emit their dependencies.
This handles things like NSSwapHostLongLongToBig and MKMapRectMake that
are static inline functions that themselves call other static inline
functions.

<rdar://problem/17227237>

Swift SVN r21080
2014-08-06 23:21:17 +00:00