agutowski created this revision.
agutowski added reviewers: rnk, hans, majnemer, thakis.
agutowski added a subscriber: cfe-commits.
Declarations for the builtins were created when suspected of being corrections
for a typo. That could trigger some absurd warnings about missing headers.
https://reviews.llvm.org/D25458
Files:
include/clang/Sema/Sema.h
lib/CodeGen/CGBuiltin.cpp
lib/Sema/SemaLookup.cpp
test/Sema/implicit-ms-builtin-decl.cpp
Index: lib/CodeGen/CGBuiltin.cpp
===================================================================
--- lib/CodeGen/CGBuiltin.cpp
+++ lib/CodeGen/CGBuiltin.cpp
@@ -795,6 +795,9 @@
Value *FnAssume = CGM.getIntrinsic(Intrinsic::assume);
return RValue::get(Builder.CreateCall(FnAssume, ArgValue));
}
+ case Builtin::BI_byteswap_ushort:
+ case Builtin::BI_byteswap_ulong:
+ case Builtin::BI_byteswap_uint64:
case Builtin::BI__builtin_bswap16:
case Builtin::BI__builtin_bswap32:
case Builtin::BI__builtin_bswap64: {
Index: lib/Sema/SemaLookup.cpp
===================================================================
--- lib/Sema/SemaLookup.cpp
+++ lib/Sema/SemaLookup.cpp
@@ -665,7 +665,7 @@
/// \brief Lookup a builtin function, when name lookup would otherwise
/// fail.
-static bool LookupBuiltin(Sema &S, LookupResult &R) {
+static bool LookupBuiltin(Sema &S, LookupResult &R, bool AllowBuiltinCreation) {
Sema::LookupNameKind NameKind = R.getLookupKind();
// If we didn't find a use of this identifier, and if the identifier
@@ -687,6 +687,9 @@
// If this is a builtin on this (or all) targets, create the decl.
if (unsigned BuiltinID = II->getBuiltinID()) {
+ if (!AllowBuiltinCreation)
+ return false;
+
// In C++ and OpenCL (spec v1.2 s6.9.f), we don't have any predefined
// library functions like 'malloc'. Instead, we'll just error.
if ((S.getLangOpts().CPlusPlus || S.getLangOpts().OpenCL) &&
@@ -820,7 +823,8 @@
// Adds all qualifying matches for a name within a decl context to the
// given lookup result. Returns true if any matches were found.
-static bool LookupDirect(Sema &S, LookupResult &R, const DeclContext *DC) {
+static bool LookupDirect(Sema &S, LookupResult &R, const DeclContext *DC,
+ bool AllowBuiltinCreation) {
bool Found = false;
// Lazily declare C++ special member functions.
@@ -838,7 +842,8 @@
}
}
- if (!Found && DC->isTranslationUnit() && LookupBuiltin(S, R))
+ if (!Found && DC->isTranslationUnit() &&
+ LookupBuiltin(S, R, AllowBuiltinCreation))
return true;
if (R.getLookupName().getNameKind()
@@ -912,19 +917,19 @@
}
// Performs C++ unqualified lookup into the given file context.
-static bool
-CppNamespaceLookup(Sema &S, LookupResult &R, ASTContext &Context,
- DeclContext *NS, UnqualUsingDirectiveSet &UDirs) {
+static bool CppNamespaceLookup(Sema &S, LookupResult &R, ASTContext &Context,
+ DeclContext *NS, UnqualUsingDirectiveSet &UDirs,
+ bool AllowBuiltinCreation) {
assert(NS && NS->isFileContext() && "CppNamespaceLookup() requires namespace!");
// Perform direct name lookup into the LookupCtx.
- bool Found = LookupDirect(S, R, NS);
+ bool Found = LookupDirect(S, R, NS, AllowBuiltinCreation);
// Perform direct name lookup into the namespaces nominated by the
// using directives whose common ancestor is this namespace.
for (const UnqualUsingEntry &UUE : UDirs.getNamespacesFor(NS))
- if (LookupDirect(S, R, UUE.getNominatedNamespace()))
+ if (LookupDirect(S, R, UUE.getNominatedNamespace(), AllowBuiltinCreation))
Found = true;
R.resolveKind();
@@ -1027,7 +1032,7 @@
};
} // end anonymous namespace
-bool Sema::CppLookupName(LookupResult &R, Scope *S) {
+bool Sema::CppLookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation) {
assert(getLangOpts().CPlusPlus && "Can perform only C++ lookup");
DeclarationName Name = R.getLookupName();
@@ -1198,7 +1203,8 @@
VisitedUsingDirectives = true;
}
- if (CppNamespaceLookup(*this, R, Context, Ctx, UDirs)) {
+ if (CppNamespaceLookup(*this, R, Context, Ctx, UDirs,
+ AllowBuiltinCreation)) {
R.resolveKind();
return true;
}
@@ -1298,7 +1304,8 @@
"We should have been looking only at file context here already.");
// Look into context considering using-directives.
- if (CppNamespaceLookup(*this, R, Context, Ctx, UDirs))
+ if (CppNamespaceLookup(*this, R, Context, Ctx, UDirs,
+ AllowBuiltinCreation))
Found = true;
}
@@ -1787,14 +1794,14 @@
}
} else {
// Perform C++ unqualified name lookup.
- if (CppLookupName(R, S))
+ if (CppLookupName(R, S, AllowBuiltinCreation))
return true;
}
// If we didn't find a use of this identifier, and if the identifier
// corresponds to a compiler builtin, create the decl object for the builtin
// now, injecting it into translation unit scope, and return it.
- if (AllowBuiltinCreation && LookupBuiltin(*this, R))
+ if (LookupBuiltin(*this, R, AllowBuiltinCreation))
return true;
// If we didn't find a use of this identifier, the ExternalSource
@@ -1871,7 +1878,8 @@
// between LookupResults.
bool UseLocal = !R.empty();
LookupResult &DirectR = UseLocal ? LocalR : R;
- bool FoundDirect = LookupDirect(S, DirectR, ND);
+ bool FoundDirect =
+ LookupDirect(S, DirectR, ND, /*AllowBuiltinCreation=*/true);
if (FoundDirect) {
// First do any local hiding.
@@ -2002,7 +2010,7 @@
}
} QL(LookupCtx);
- if (LookupDirect(*this, R, LookupCtx)) {
+ if (LookupDirect(*this, R, LookupCtx, /*AllowBuiltinCreation=*/true)) {
R.resolveKind();
if (isa<CXXRecordDecl>(LookupCtx))
R.setNamingClass(cast<CXXRecordDecl>(LookupCtx));
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -2846,7 +2846,7 @@
TypoRecoveryCallback;
private:
- bool CppLookupName(LookupResult &R, Scope *S);
+ bool CppLookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation);
struct TypoExprState {
std::unique_ptr<TypoCorrectionConsumer> Consumer;
Index: test/Sema/implicit-ms-builtin-decl.cpp
===================================================================
--- /dev/null
+++ test/Sema/implicit-ms-builtin-decl.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -triple x86_64-windows -fsyntax-only -verify %s -fms-extensions
+// RUN: %clang_cc1 -triple i386-windows -fsyntax-only -verify %s -fms-extensions
+
+void f() {
+ (void)_byteswap_ushort(42); // expected-error{{use of undeclared identifier '_byteswap_ushort'}}
+ (void)_byteswap_uint64(42LL); // expected-error{{use of undeclared identifier '_byteswap_uint64'}}
+}
+
+void _byteswap_ulong();
+
+unsigned short _byteswap_ushort(unsigned short);
+unsigned long long _byteswap_uint64(unsigned long long);
+
+void g() {
+ (void)_byteswap_ushort(42);
+ (void)_byteswap_uint64(42LL);
+}
+
+#if defined(__x86_64__)
+void h() {
+ (void)__mulh(21, 2); // expected-warning{{implicitly declaring library function '__mulh'}} \
+ // expected-note{{include the header <intrin.h> or explicitly provide a declaration for '__mulh'}}
+ (void)__umulh(21, 2); // expected-warning{{implicitly declaring library function '__umulh'}} \
+ // expected-note{{include the header <intrin.h> or explicitly provide a declaration for '__umulh'}}
+}
+
+long long __mulh(long long, long long);
+unsigned long long __umulh(unsigned long long, unsigned long long);
+
+void i() {
+ (void)__mulh(21, 2);
+ (void)__umulh(21, 2);
+}
+#endif
+
+#if defined(__i386__)
+void h() {
+ (void)__mulh(21LL, 2LL); // expected-error{{use of undeclared identifier '__mulh'}}
+ (void)__umulh(21ULL, 2ULL); // expected-error{{use of undeclared identifier '__umulh'}}
+}
+#endif
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits