diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 22 | ||||
| -rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 11 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGVtable.cpp | 18 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 32 | 
6 files changed, 51 insertions, 37 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index bbbb19a35b4..b30d335918a 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -643,23 +643,15 @@ QualType CXXMethodDecl::getThisType(ASTContext &C) const {    return C.getPointerType(ClassTy);  } -static bool MethodHasBody(const CXXMethodDecl *MD, const FunctionDecl *&fn) { -  // Simple case: function has a body -  if (MD->getBody(fn)) -    return true; - -  // Complex case: function is an instantiation of a function which has a -  // body, but the definition hasn't been instantiated. -  const FunctionDecl *PatternDecl = MD->getTemplateInstantiationPattern(); -  if (PatternDecl && PatternDecl->getBody(fn)) -    return true; - -  return false; -} -  bool CXXMethodDecl::hasInlineBody() const { +  // If this function is a template instantiation, look at the template from  +  // which it was instantiated. +  const FunctionDecl *CheckFn = getTemplateInstantiationPattern(); +  if (!CheckFn) +    CheckFn = this; +      const FunctionDecl *fn; -  return MethodHasBody(this, fn) && !fn->isOutOfLine(); +  return CheckFn->getBody(fn) && !fn->isOutOfLine();  }  CXXBaseOrMemberInitializer:: diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index c914f3f82e8..cfd89eaed35 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -719,11 +719,6 @@ ASTRecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) {    // If a class isnt' polymorphic it doesn't have a key function.    if (!RD->isPolymorphic())      return 0; -   -  // A class template specialization or instantation does not have a key -  // function. -  if (RD->getTemplateSpecializationKind() != TSK_Undeclared) -    return 0;    // A class inside an anonymous namespace doesn't have a key function.  (Or    // at least, there's no point to assigning a key function to such a class; @@ -741,13 +736,13 @@ ASTRecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) {      if (MD->isPure())        continue; -    if (MD->isInlineSpecified()) -      continue; -          // Ignore implicit member functions, they are always marked as inline, but      // they don't have a body until they're defined.      if (MD->isImplicit())        continue; +     +    if (MD->isInlineSpecified()) +      continue;      if (MD->hasInlineBody())        continue; diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index ba5a0c35439..ca148da9560 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/lib/CodeGen/CGVtable.cpp @@ -1493,8 +1493,22 @@ void CGVtableInfo::MaybeEmitVtable(GlobalDecl GD) {    llvm::GlobalVariable::LinkageTypes Linkage;    if (RD->isInAnonymousNamespace() || !RD->hasLinkage())      Linkage = llvm::GlobalVariable::InternalLinkage; -  else if (KeyFunction && !MD->isInlined()) -    Linkage = llvm::GlobalVariable::ExternalLinkage; +  else if (KeyFunction && !MD->isInlined()) { +    switch (MD->getTemplateSpecializationKind()) { +    case TSK_Undeclared: +    case TSK_ExplicitSpecialization: +      Linkage = llvm::GlobalVariable::ExternalLinkage; +      break; + +    case TSK_ImplicitInstantiation: +    case TSK_ExplicitInstantiationDeclaration: +      // FIXME: could an explicit instantiation declaration imply +      // available_externally linkage? +    case TSK_ExplicitInstantiationDefinition: +      Linkage = llvm::GlobalVariable::WeakODRLinkage; +      break; +    } +  }    else      Linkage = llvm::GlobalVariable::WeakODRLinkage; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 16a01cfd58f..85d57e7cbec 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -547,7 +547,8 @@ bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {        const CXXRecordDecl *RD = MD->getParent();        if (MD->isOutOfLine() && RD->isDynamicClass()) {          const CXXMethodDecl *KeyFunction = getContext().getKeyFunction(RD); -        if (KeyFunction == MD->getCanonicalDecl()) +        if (KeyFunction &&  +            KeyFunction->getCanonicalDecl() == MD->getCanonicalDecl())            return false;        }      } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index a15c5fea213..0fc61e3b587 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3749,7 +3749,7 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {    if (getLangOptions().CPlusPlus) {      // Make sure we mark the destructor as used if necessary.      QualType InitType = VDecl->getType(); -    if (const ArrayType *Array = Context.getAsArrayType(InitType)) +    while (const ArrayType *Array = Context.getAsArrayType(InitType))        InitType = Context.getBaseElementType(Array);      if (InitType->isRecordType())        FinalizeVarWithDestructor(VDecl, InitType); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 204d7764682..ecf95d7eb66 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -5702,19 +5702,31 @@ void Sema::MaybeMarkVirtualMembersReferenced(SourceLocation Loc,        ClassesWithUnmarkedVirtualMembers.insert(std::make_pair(RD, Loc));      return;    } -   -  const CXXMethodDecl *KeyFunction = Context.getKeyFunction(RD); -  if (!KeyFunction) { -    // This record does not have a key function, so we assume that the vtable -    // will be emitted when it's used by the constructor. -    if (!isa<CXXConstructorDecl>(MD)) +  switch (RD->getTemplateSpecializationKind()) { +  case TSK_Undeclared: +  case TSK_ExplicitSpecialization: { +    const CXXMethodDecl *KeyFunction = Context.getKeyFunction(RD); + +    if (!KeyFunction) { +      // This record does not have a key function, so we assume that the vtable +      // will be emitted when it's used by the constructor. +      if (!isa<CXXConstructorDecl>(MD)) +        return; +    } else if (KeyFunction->getCanonicalDecl() != MD->getCanonicalDecl()) { +      // We don't have the right key function.        return; -  } else if (KeyFunction->getCanonicalDecl() != MD->getCanonicalDecl()) { -    // We don't have the right key function. -    return; +    } +    break;    } -   + +  case TSK_ImplicitInstantiation: +  case TSK_ExplicitInstantiationDeclaration: +  case TSK_ExplicitInstantiationDefinition: +    // Always mark the virtual members of an instantiated template. +    break; +  } +    // Mark the members as referenced.    MarkVirtualMembersReferenced(Loc, RD);    ClassesWithUnmarkedVirtualMembers.erase(RD);  | 

