diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-06-10 19:12:52 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-06-10 19:12:52 +0000 | 
| commit | 97bc6c731eabb6212f094302b94f3f0f9534ebdf (patch) | |
| tree | 471dda8f5419bb81beedeeef3b8975938d7e7340 /contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp | |
| parent | 3adc74c768226112b373d0bcacee73521b0aed2a (diff) | |
| parent | 85d8b2bbe386bcfe669575d05b61482d7be07e5d (diff) | |
Notes
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp | 122 | 
1 files changed, 65 insertions, 57 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp index b1dfe0e95e2d..c80ef2d2bdc1 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp @@ -1345,57 +1345,6 @@ static bool findCircularInheritance(const CXXRecordDecl *Class,    return false;  } -/// \brief Perform propagation of DLL attributes from a derived class to a -/// templated base class for MS compatibility. -static void propagateDLLAttrToBaseClassTemplate( -    Sema &S, CXXRecordDecl *Class, Attr *ClassAttr, -    ClassTemplateSpecializationDecl *BaseTemplateSpec, SourceLocation BaseLoc) { -  if (getDLLAttr( -          BaseTemplateSpec->getSpecializedTemplate()->getTemplatedDecl())) { -    // If the base class template has a DLL attribute, don't try to change it. -    return; -  } - -  if (BaseTemplateSpec->getSpecializationKind() == TSK_Undeclared) { -    // If the base class is not already specialized, we can do the propagation. -    auto *NewAttr = cast<InheritableAttr>(ClassAttr->clone(S.getASTContext())); -    NewAttr->setInherited(true); -    BaseTemplateSpec->addAttr(NewAttr); -    return; -  } - -  bool DifferentAttribute = false; -  if (Attr *SpecializationAttr = getDLLAttr(BaseTemplateSpec)) { -    if (!SpecializationAttr->isInherited()) { -      // The template has previously been specialized or instantiated with an -      // explicit attribute. We should not try to change it. -      return; -    } -    if (SpecializationAttr->getKind() == ClassAttr->getKind()) { -      // The specialization already has the right attribute. -      return; -    } -    DifferentAttribute = true; -  } - -  // The template was previously instantiated or explicitly specialized without -  // a dll attribute, or the template was previously instantiated with a -  // different inherited attribute. It's too late for us to change the -  // attribute, so warn that this is unsupported. -  S.Diag(BaseLoc, diag::warn_attribute_dll_instantiated_base_class) -      << BaseTemplateSpec->isExplicitSpecialization() << DifferentAttribute; -  S.Diag(ClassAttr->getLocation(), diag::note_attribute); -  if (BaseTemplateSpec->isExplicitSpecialization()) { -    S.Diag(BaseTemplateSpec->getLocation(), -           diag::note_template_class_explicit_specialization_was_here) -        << BaseTemplateSpec; -  } else { -    S.Diag(BaseTemplateSpec->getPointOfInstantiation(), -           diag::note_template_class_instantiation_was_here) -        << BaseTemplateSpec; -  } -} -  /// \brief Check the validity of a C++ base class specifier.  ///  /// \returns a new CXXBaseSpecifier if well-formed, emits diagnostics @@ -1467,8 +1416,8 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,      if (Attr *ClassAttr = getDLLAttr(Class)) {        if (auto *BaseTemplate = dyn_cast_or_null<ClassTemplateSpecializationDecl>(                BaseType->getAsCXXRecordDecl())) { -        propagateDLLAttrToBaseClassTemplate(*this, Class, ClassAttr, -                                            BaseTemplate, BaseLoc); +        propagateDLLAttrToBaseClassTemplate(Class, ClassAttr, BaseTemplate, +                                            BaseLoc);        }      }    } @@ -4791,8 +4740,9 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) {    TemplateSpecializationKind TSK = Class->getTemplateSpecializationKind(); -  // Don't dllexport explicit class template instantiation declarations. -  if (ClassExported && TSK == TSK_ExplicitInstantiationDeclaration) { +  // Ignore explicit dllexport on explicit class template instantiation declarations. +  if (ClassExported && !ClassAttr->isInherited() && +      TSK == TSK_ExplicitInstantiationDeclaration) {      Class->dropAttr<DLLExportAttr>();      return;    } @@ -4840,12 +4790,15 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) {      }      if (MD && ClassExported) { +      if (TSK == TSK_ExplicitInstantiationDeclaration) +        // Don't go any further if this is just an explicit instantiation +        // declaration. +        continue; +        if (MD->isUserProvided()) {          // Instantiate non-default class member functions ...          // .. except for certain kinds of template specializations. -        if (TSK == TSK_ExplicitInstantiationDeclaration) -          continue;          if (TSK == TSK_ImplicitInstantiation && !ClassAttr->isInherited())            continue; @@ -4876,6 +4829,61 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) {    }  } +/// \brief Perform propagation of DLL attributes from a derived class to a +/// templated base class for MS compatibility. +void Sema::propagateDLLAttrToBaseClassTemplate( +    CXXRecordDecl *Class, Attr *ClassAttr, +    ClassTemplateSpecializationDecl *BaseTemplateSpec, SourceLocation BaseLoc) { +  if (getDLLAttr( +          BaseTemplateSpec->getSpecializedTemplate()->getTemplatedDecl())) { +    // If the base class template has a DLL attribute, don't try to change it. +    return; +  } + +  auto TSK = BaseTemplateSpec->getSpecializationKind(); +  if (!getDLLAttr(BaseTemplateSpec) && +      (TSK == TSK_Undeclared || TSK == TSK_ExplicitInstantiationDeclaration || +       TSK == TSK_ImplicitInstantiation)) { +    // The template hasn't been instantiated yet (or it has, but only as an +    // explicit instantiation declaration or implicit instantiation, which means +    // we haven't codegenned any members yet), so propagate the attribute. +    auto *NewAttr = cast<InheritableAttr>(ClassAttr->clone(getASTContext())); +    NewAttr->setInherited(true); +    BaseTemplateSpec->addAttr(NewAttr); + +    // If the template is already instantiated, checkDLLAttributeRedeclaration() +    // needs to be run again to work see the new attribute. Otherwise this will +    // get run whenever the template is instantiated. +    if (TSK != TSK_Undeclared) +      checkClassLevelDLLAttribute(BaseTemplateSpec); + +    return; +  } + +  if (getDLLAttr(BaseTemplateSpec)) { +    // The template has already been specialized or instantiated with an +    // attribute, explicitly or through propagation. We should not try to change +    // it. +    return; +  } + +  // The template was previously instantiated or explicitly specialized without +  // a dll attribute, It's too late for us to add an attribute, so warn that +  // this is unsupported. +  Diag(BaseLoc, diag::warn_attribute_dll_instantiated_base_class) +      << BaseTemplateSpec->isExplicitSpecialization(); +  Diag(ClassAttr->getLocation(), diag::note_attribute); +  if (BaseTemplateSpec->isExplicitSpecialization()) { +    Diag(BaseTemplateSpec->getLocation(), +           diag::note_template_class_explicit_specialization_was_here) +        << BaseTemplateSpec; +  } else { +    Diag(BaseTemplateSpec->getPointOfInstantiation(), +           diag::note_template_class_instantiation_was_here) +        << BaseTemplateSpec; +  } +} +  /// \brief Perform semantic checks on a class definition that has been  /// completing, introducing implicitly-declared members, checking for  /// abstract types, etc.  | 
