diff options
| author | Andrey Bokhanko <andreybokhanko@gmail.com> | 2015-09-14 21:29:57 +0000 |
|---|---|---|
| committer | Andrey Bokhanko <andreybokhanko@gmail.com> | 2015-09-14 21:29:57 +0000 |
| commit | ddc04ef4933dbb176fde074613508d5311d3c338 (patch) | |
| tree | 1866941fa59589cf20edab4bb4851d18119c4742 /clang/lib/Sema | |
| parent | 022bdc7d7361f48a359194e630e8b16f1d134cfe (diff) | |
| download | bcm5719-llvm-ddc04ef4933dbb176fde074613508d5311d3c338.tar.gz bcm5719-llvm-ddc04ef4933dbb176fde074613508d5311d3c338.zip | |
PR24595: Ignore calling convention modifiers for structors in MS ABI.
MS compiler ignores calling convention modifiers for structors. This patch makes
clang do the same (for MS ABI). This fixes PR24595 and makes vswriter.h header
(from Windows SDK 8.1) compilable.
Differential Revision: http://reviews.llvm.org/D12402
llvm-svn: 247619
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/DeclSpec.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaType.cpp | 41 |
3 files changed, 37 insertions, 12 deletions
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp index 357f2d3a030..2cf35b9d280 100644 --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -351,6 +351,11 @@ bool Declarator::isStaticMember() { getName().OperatorFunctionId.Operator)); } +bool Declarator::isCtorOrDtor() { + return (getName().getKind() == UnqualifiedId::IK_ConstructorName) || + (getName().getKind() == UnqualifiedId::IK_DestructorName); +} + bool DeclSpec::hasTagDefinition() const { if (!TypeSpecOwned) return false; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 43aa2d73fc6..8501bc5b224 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -7244,7 +7244,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, << DeclSpec::getSpecifierName(TSCS); if (D.isFirstDeclarationOfMember()) - adjustMemberFunctionCC(R, D.isStaticMember()); + adjustMemberFunctionCC(R, D.isStaticMember(), D.isCtorOrDtor(), + D.getIdentifierLoc()); bool isFriend = false; FunctionTemplateDecl *FunctionTemplate = nullptr; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 012b65b799f..63045992276 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2269,8 +2269,11 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class, // Adjust the default free function calling convention to the default method // calling convention. + bool IsCtorOrDtor = + (Entity.getNameKind() == DeclarationName::CXXConstructorName) || + (Entity.getNameKind() == DeclarationName::CXXDestructorName); if (T->isFunctionType()) - adjustMemberFunctionCC(T, /*IsStatic=*/false); + adjustMemberFunctionCC(T, /*IsStatic=*/false, IsCtorOrDtor, Loc); return Context.getMemberPointerType(T, Class.getTypePtr()); } @@ -5842,25 +5845,41 @@ bool Sema::hasExplicitCallingConv(QualType &T) { return false; } -void Sema::adjustMemberFunctionCC(QualType &T, bool IsStatic) { +void Sema::adjustMemberFunctionCC(QualType &T, bool IsStatic, bool IsCtorOrDtor, + SourceLocation Loc) { FunctionTypeUnwrapper Unwrapped(*this, T); const FunctionType *FT = Unwrapped.get(); bool IsVariadic = (isa<FunctionProtoType>(FT) && cast<FunctionProtoType>(FT)->isVariadic()); - - // Only adjust types with the default convention. For example, on Windows we - // should adjust a __cdecl type to __thiscall for instance methods, and a - // __thiscall type to __cdecl for static methods. CallingConv CurCC = FT->getCallConv(); - CallingConv FromCC = - Context.getDefaultCallingConvention(IsVariadic, IsStatic); CallingConv ToCC = Context.getDefaultCallingConvention(IsVariadic, !IsStatic); - if (CurCC != FromCC || FromCC == ToCC) - return; - if (hasExplicitCallingConv(T)) + if (CurCC == ToCC) return; + // MS compiler ignores explicit calling convention attributes on structors. We + // should do the same. + if (Context.getTargetInfo().getCXXABI().isMicrosoft() && IsCtorOrDtor) { + // Issue a warning on ignored calling convention -- except of __stdcall. + // Again, this is what MS compiler does. + if (CurCC != CC_X86StdCall) + Diag(Loc, diag::warn_cconv_structors) + << FunctionType::getNameForCallConv(CurCC); + // Default adjustment. + } else { + // Only adjust types with the default convention. For example, on Windows + // we should adjust a __cdecl type to __thiscall for instance methods, and a + // __thiscall type to __cdecl for static methods. + CallingConv DefaultCC = + Context.getDefaultCallingConvention(IsVariadic, IsStatic); + + if (CurCC != DefaultCC || DefaultCC == ToCC) + return; + + if (hasExplicitCallingConv(T)) + return; + } + FT = Context.adjustFunctionType(FT, FT->getExtInfo().withCallingConv(ToCC)); QualType Wrapped = Unwrapped.wrap(*this, FT); T = Context.getAdjustedType(T, Wrapped); |

