2006-10-16 06:34:45 +08:00
|
|
|
//===--- Decl.cpp - Declaration AST Node Implementation -------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 03:59:25 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2006-10-16 06:34:45 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2008-06-04 21:04:04 +08:00
|
|
|
// This file implements the Decl subclasses.
|
2006-10-16 06:34:45 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "clang/AST/Decl.h"
|
2008-03-15 14:12:44 +08:00
|
|
|
#include "clang/AST/ASTContext.h"
|
2014-04-04 00:32:21 +08:00
|
|
|
#include "clang/AST/ASTLambda.h"
|
2012-12-01 23:09:41 +08:00
|
|
|
#include "clang/AST/ASTMutationListener.h"
|
|
|
|
#include "clang/AST/Attr.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/AST/DeclCXX.h"
|
|
|
|
#include "clang/AST/DeclObjC.h"
|
|
|
|
#include "clang/AST/DeclTemplate.h"
|
2008-12-18 07:39:55 +08:00
|
|
|
#include "clang/AST/Expr.h"
|
2009-12-16 03:16:31 +08:00
|
|
|
#include "clang/AST/ExprCXX.h"
|
2009-05-30 04:38:28 +08:00
|
|
|
#include "clang/AST/PrettyPrinter.h"
|
2012-12-01 23:09:41 +08:00
|
|
|
#include "clang/AST/Stmt.h"
|
|
|
|
#include "clang/AST/TypeLoc.h"
|
2009-06-14 09:54:56 +08:00
|
|
|
#include "clang/Basic/Builtins.h"
|
2008-08-11 12:54:23 +08:00
|
|
|
#include "clang/Basic/IdentifierTable.h"
|
2011-12-03 07:23:56 +08:00
|
|
|
#include "clang/Basic/Module.h"
|
2010-05-12 05:36:43 +08:00
|
|
|
#include "clang/Basic/Specifiers.h"
|
2011-03-26 20:10:19 +08:00
|
|
|
#include "clang/Basic/TargetInfo.h"
|
2014-10-17 04:54:52 +08:00
|
|
|
#include "clang/Frontend/FrontendDiagnostic.h"
|
2009-09-04 09:14:41 +08:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2011-09-22 02:16:56 +08:00
|
|
|
#include <algorithm>
|
|
|
|
|
2006-10-25 13:11:20 +08:00
|
|
|
using namespace clang;
|
2006-10-16 06:34:45 +08:00
|
|
|
|
2013-10-07 16:02:11 +08:00
|
|
|
Decl *clang::getPrimaryMergedDecl(Decl *D) {
|
|
|
|
return D->getASTContext().getPrimaryMergedDecl(D);
|
|
|
|
}
|
|
|
|
|
2014-09-03 10:33:22 +08:00
|
|
|
// Defined here so that it can be inlined into its direct callers.
|
|
|
|
bool Decl::isOutOfLine() const {
|
|
|
|
return !getLexicalDeclContext()->Equals(getDeclContext());
|
|
|
|
}
|
|
|
|
|
2008-03-31 08:36:02 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2009-01-20 09:17:11 +08:00
|
|
|
// NamedDecl Implementation
|
2008-11-10 07:41:00 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2013-02-16 08:17:33 +08:00
|
|
|
// Visibility rules aren't rigorously externally specified, but here
|
|
|
|
// are the basic principles behind what we implement:
|
|
|
|
//
|
|
|
|
// 1. An explicit visibility attribute is generally a direct expression
|
|
|
|
// of the user's intent and should be honored. Only the innermost
|
|
|
|
// visibility attribute applies. If no visibility attribute applies,
|
|
|
|
// global visibility settings are considered.
|
|
|
|
//
|
|
|
|
// 2. There is one caveat to the above: on or in a template pattern,
|
|
|
|
// an explicit visibility attribute is just a default rule, and
|
|
|
|
// visibility can be decreased by the visibility of template
|
|
|
|
// arguments. But this, too, has an exception: an attribute on an
|
|
|
|
// explicit specialization or instantiation causes all the visibility
|
|
|
|
// restrictions of the template arguments to be ignored.
|
|
|
|
//
|
|
|
|
// 3. A variable that does not otherwise have explicit visibility can
|
|
|
|
// be restricted by the visibility of its type.
|
|
|
|
//
|
|
|
|
// 4. A visibility restriction is explicit if it comes from an
|
|
|
|
// attribute (or something like it), not a global visibility setting.
|
|
|
|
// When emitting a reference to an external symbol, visibility
|
|
|
|
// restrictions are ignored unless they are explicit.
|
2013-02-20 09:54:26 +08:00
|
|
|
//
|
|
|
|
// 5. When computing the visibility of a non-type, including a
|
|
|
|
// non-type member of a class, only non-type visibility restrictions
|
|
|
|
// are considered: the 'visibility' attribute, global value-visibility
|
|
|
|
// settings, and a few special cases like __private_extern.
|
|
|
|
//
|
|
|
|
// 6. When computing the visibility of a type, including a type member
|
|
|
|
// of a class, only type visibility restrictions are considered:
|
|
|
|
// the 'type_visibility' attribute and global type-visibility settings.
|
|
|
|
// However, a 'visibility' attribute counts as a 'type_visibility'
|
|
|
|
// attribute on any declaration that only has the former.
|
|
|
|
//
|
|
|
|
// The visibility of a "secondary" entity, like a template argument,
|
|
|
|
// is computed using the kind of that entity, not the kind of the
|
|
|
|
// primary entity for which we are computing visibility. For example,
|
|
|
|
// the visibility of a specialization of either of these templates:
|
|
|
|
// template <class T, bool (&compare)(T, X)> bool has_match(list<T>, X);
|
|
|
|
// template <class T, bool (&compare)(T, X)> class matcher;
|
|
|
|
// is restricted according to the type visibility of the argument 'T',
|
|
|
|
// the type visibility of 'bool(&)(T,X)', and the value visibility of
|
|
|
|
// the argument function 'compare'. That 'has_match' is a value
|
|
|
|
// and 'matcher' is a type only matters when looking for attributes
|
|
|
|
// and settings from the immediate context.
|
2013-02-16 08:17:33 +08:00
|
|
|
|
2013-02-22 07:42:58 +08:00
|
|
|
const unsigned IgnoreExplicitVisibilityBit = 2;
|
2013-05-29 03:43:11 +08:00
|
|
|
const unsigned IgnoreAllVisibilityBit = 4;
|
2013-02-22 07:42:58 +08:00
|
|
|
|
2013-02-16 08:17:33 +08:00
|
|
|
/// Kinds of LV computation. The linkage side of the computation is
|
|
|
|
/// always the same, but different things can change how visibility is
|
|
|
|
/// computed.
|
|
|
|
enum LVComputationKind {
|
2013-02-22 07:42:58 +08:00
|
|
|
/// Do an LV computation for, ultimately, a type.
|
|
|
|
/// Visibility may be restricted by type visibility settings and
|
|
|
|
/// the visibility of template arguments.
|
2013-02-20 09:54:26 +08:00
|
|
|
LVForType = NamedDecl::VisibilityForType,
|
|
|
|
|
2013-02-22 07:42:58 +08:00
|
|
|
/// Do an LV computation for, ultimately, a non-type declaration.
|
|
|
|
/// Visibility may be restricted by value visibility settings and
|
|
|
|
/// the visibility of template arguments.
|
2013-02-20 09:54:26 +08:00
|
|
|
LVForValue = NamedDecl::VisibilityForValue,
|
2013-02-16 08:17:33 +08:00
|
|
|
|
2013-02-22 07:42:58 +08:00
|
|
|
/// Do an LV computation for, ultimately, a type that already has
|
|
|
|
/// some sort of explicit visibility. Visibility may only be
|
|
|
|
/// restricted by the visibility of template arguments.
|
|
|
|
LVForExplicitType = (LVForType | IgnoreExplicitVisibilityBit),
|
2013-02-20 09:54:26 +08:00
|
|
|
|
2013-02-22 07:42:58 +08:00
|
|
|
/// Do an LV computation for, ultimately, a non-type declaration
|
|
|
|
/// that already has some sort of explicit visibility. Visibility
|
|
|
|
/// may only be restricted by the visibility of template arguments.
|
2013-05-29 03:43:11 +08:00
|
|
|
LVForExplicitValue = (LVForValue | IgnoreExplicitVisibilityBit),
|
|
|
|
|
|
|
|
/// Do an LV computation when we only care about the linkage.
|
|
|
|
LVForLinkageOnly =
|
|
|
|
LVForValue | IgnoreExplicitVisibilityBit | IgnoreAllVisibilityBit
|
2013-02-16 08:17:33 +08:00
|
|
|
};
|
|
|
|
|
2013-02-20 09:54:26 +08:00
|
|
|
/// Does this computation kind permit us to consider additional
|
|
|
|
/// visibility settings from attributes and the like?
|
|
|
|
static bool hasExplicitVisibilityAlready(LVComputationKind computation) {
|
2013-02-22 07:42:58 +08:00
|
|
|
return ((unsigned(computation) & IgnoreExplicitVisibilityBit) != 0);
|
2013-02-20 09:54:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Given an LVComputationKind, return one of the same type/value sort
|
|
|
|
/// that records that it already has explicit visibility.
|
|
|
|
static LVComputationKind
|
|
|
|
withExplicitVisibilityAlready(LVComputationKind oldKind) {
|
|
|
|
LVComputationKind newKind =
|
2013-02-22 07:42:58 +08:00
|
|
|
static_cast<LVComputationKind>(unsigned(oldKind) |
|
|
|
|
IgnoreExplicitVisibilityBit);
|
2013-02-20 09:54:26 +08:00
|
|
|
assert(oldKind != LVForType || newKind == LVForExplicitType);
|
|
|
|
assert(oldKind != LVForValue || newKind == LVForExplicitValue);
|
|
|
|
assert(oldKind != LVForExplicitType || newKind == LVForExplicitType);
|
|
|
|
assert(oldKind != LVForExplicitValue || newKind == LVForExplicitValue);
|
|
|
|
return newKind;
|
|
|
|
}
|
|
|
|
|
2013-02-21 06:23:23 +08:00
|
|
|
static Optional<Visibility> getExplicitVisibility(const NamedDecl *D,
|
|
|
|
LVComputationKind kind) {
|
2013-02-20 09:54:26 +08:00
|
|
|
assert(!hasExplicitVisibilityAlready(kind) &&
|
|
|
|
"asking for explicit visibility when we shouldn't be");
|
|
|
|
return D->getExplicitVisibility((NamedDecl::ExplicitVisibilityKind) kind);
|
|
|
|
}
|
|
|
|
|
2013-02-16 08:17:33 +08:00
|
|
|
/// Is the given declaration a "type" or a "value" for the purposes of
|
|
|
|
/// visibility computation?
|
|
|
|
static bool usesTypeVisibility(const NamedDecl *D) {
|
2013-02-19 09:57:35 +08:00
|
|
|
return isa<TypeDecl>(D) ||
|
|
|
|
isa<ClassTemplateDecl>(D) ||
|
|
|
|
isa<ObjCInterfaceDecl>(D);
|
2013-02-16 08:17:33 +08:00
|
|
|
}
|
|
|
|
|
2013-02-22 07:42:58 +08:00
|
|
|
/// Does the given declaration have member specialization information,
|
|
|
|
/// and if so, is it an explicit specialization?
|
|
|
|
template <class T> static typename
|
2014-03-07 22:30:23 +08:00
|
|
|
std::enable_if<!std::is_base_of<RedeclarableTemplateDecl, T>::value, bool>::type
|
2013-02-22 07:42:58 +08:00
|
|
|
isExplicitMemberSpecialization(const T *D) {
|
|
|
|
if (const MemberSpecializationInfo *member =
|
|
|
|
D->getMemberSpecializationInfo()) {
|
|
|
|
return member->isExplicitSpecialization();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// For templates, this question is easier: a member template can't be
|
|
|
|
/// explicitly instantiated, so there's a single bit indicating whether
|
|
|
|
/// or not this is an explicit member specialization.
|
|
|
|
static bool isExplicitMemberSpecialization(const RedeclarableTemplateDecl *D) {
|
|
|
|
return D->isMemberSpecialization();
|
|
|
|
}
|
|
|
|
|
2013-02-20 09:54:26 +08:00
|
|
|
/// Given a visibility attribute, return the explicit visibility
|
|
|
|
/// associated with it.
|
|
|
|
template <class T>
|
|
|
|
static Visibility getVisibilityFromAttr(const T *attr) {
|
|
|
|
switch (attr->getVisibility()) {
|
|
|
|
case T::Default:
|
|
|
|
return DefaultVisibility;
|
|
|
|
case T::Hidden:
|
|
|
|
return HiddenVisibility;
|
|
|
|
case T::Protected:
|
|
|
|
return ProtectedVisibility;
|
|
|
|
}
|
|
|
|
llvm_unreachable("bad visibility kind");
|
|
|
|
}
|
|
|
|
|
2013-02-16 08:17:33 +08:00
|
|
|
/// Return the explicit visibility of the given declaration.
|
2013-02-21 06:23:23 +08:00
|
|
|
static Optional<Visibility> getVisibilityOf(const NamedDecl *D,
|
2013-02-20 09:54:26 +08:00
|
|
|
NamedDecl::ExplicitVisibilityKind kind) {
|
|
|
|
// If we're ultimately computing the visibility of a type, look for
|
|
|
|
// a 'type_visibility' attribute before looking for 'visibility'.
|
|
|
|
if (kind == NamedDecl::VisibilityForType) {
|
|
|
|
if (const TypeVisibilityAttr *A = D->getAttr<TypeVisibilityAttr>()) {
|
|
|
|
return getVisibilityFromAttr(A);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-03-26 20:10:19 +08:00
|
|
|
// If this declaration has an explicit visibility attribute, use it.
|
|
|
|
if (const VisibilityAttr *A = D->getAttr<VisibilityAttr>()) {
|
2013-02-20 09:54:26 +08:00
|
|
|
return getVisibilityFromAttr(A);
|
2010-10-28 12:18:25 +08:00
|
|
|
}
|
2010-12-18 11:30:47 +08:00
|
|
|
|
2011-03-26 20:10:19 +08:00
|
|
|
// If we're on Mac OS X, an 'availability' for Mac OS X attribute
|
|
|
|
// implies visibility(default).
|
2011-09-02 08:18:52 +08:00
|
|
|
if (D->getASTContext().getTargetInfo().getTriple().isOSDarwin()) {
|
2014-03-11 01:08:28 +08:00
|
|
|
for (const auto *A : D->specific_attrs<AvailabilityAttr>())
|
|
|
|
if (A->getPlatform()->getName().equals("macosx"))
|
2011-03-26 20:10:19 +08:00
|
|
|
return DefaultVisibility;
|
2010-10-23 05:05:15 +08:00
|
|
|
}
|
2011-03-26 20:10:19 +08:00
|
|
|
|
2013-02-21 09:47:18 +08:00
|
|
|
return None;
|
2010-10-23 05:05:15 +08:00
|
|
|
}
|
|
|
|
|
2013-05-29 12:55:30 +08:00
|
|
|
static LinkageInfo
|
|
|
|
getLVForType(const Type &T, LVComputationKind computation) {
|
|
|
|
if (computation == LVForLinkageOnly)
|
|
|
|
return LinkageInfo(T.getLinkage(), DefaultVisibility, true);
|
|
|
|
return T.getLinkageAndVisibility();
|
|
|
|
}
|
|
|
|
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
/// \brief Get the most restrictive linkage for the types in the given
|
2013-02-16 08:17:33 +08:00
|
|
|
/// template parameter list. For visibility purposes, template
|
|
|
|
/// parameters are part of the signature of a template.
|
2012-01-14 08:30:36 +08:00
|
|
|
static LinkageInfo
|
2014-04-23 13:16:48 +08:00
|
|
|
getLVForTemplateParameterList(const TemplateParameterList *Params,
|
2013-05-29 12:55:30 +08:00
|
|
|
LVComputationKind computation) {
|
2013-02-16 08:17:33 +08:00
|
|
|
LinkageInfo LV;
|
2014-04-23 13:16:48 +08:00
|
|
|
for (const NamedDecl *P : *Params) {
|
2013-02-16 08:17:33 +08:00
|
|
|
// Template type parameters are the most common and never
|
|
|
|
// contribute to visibility, pack or not.
|
2014-04-23 13:16:48 +08:00
|
|
|
if (isa<TemplateTypeParmDecl>(P))
|
2013-02-16 08:17:33 +08:00
|
|
|
continue;
|
|
|
|
|
|
|
|
// Non-type template parameters can be restricted by the value type, e.g.
|
|
|
|
// template <enum X> class A { ... };
|
|
|
|
// We have to be careful here, though, because we can be dealing with
|
|
|
|
// dependent types.
|
2014-04-23 13:16:48 +08:00
|
|
|
if (const NonTypeTemplateParmDecl *NTTP =
|
|
|
|
dyn_cast<NonTypeTemplateParmDecl>(P)) {
|
2013-02-16 08:17:33 +08:00
|
|
|
// Handle the non-pack case first.
|
|
|
|
if (!NTTP->isExpandedParameterPack()) {
|
|
|
|
if (!NTTP->getType()->isDependentType()) {
|
2013-05-29 12:55:30 +08:00
|
|
|
LV.merge(getLVForType(*NTTP->getType(), computation));
|
2011-01-20 04:10:05 +08:00
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
2012-01-02 14:26:22 +08:00
|
|
|
|
2013-02-16 08:17:33 +08:00
|
|
|
// Look at all the types in an expanded pack.
|
|
|
|
for (unsigned i = 0, n = NTTP->getNumExpansionTypes(); i != n; ++i) {
|
|
|
|
QualType type = NTTP->getExpansionType(i);
|
|
|
|
if (!type->isDependentType())
|
2013-02-27 10:27:19 +08:00
|
|
|
LV.merge(type->getLinkageAndVisibility());
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
}
|
2013-02-16 08:17:33 +08:00
|
|
|
continue;
|
2011-01-20 04:10:05 +08:00
|
|
|
}
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
|
2013-02-16 08:17:33 +08:00
|
|
|
// Template template parameters can be restricted by their
|
|
|
|
// template parameters, recursively.
|
2014-04-23 13:16:48 +08:00
|
|
|
const TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(P);
|
2013-02-16 08:17:33 +08:00
|
|
|
|
|
|
|
// Handle the non-pack case first.
|
|
|
|
if (!TTP->isExpandedParameterPack()) {
|
2013-05-29 12:55:30 +08:00
|
|
|
LV.merge(getLVForTemplateParameterList(TTP->getTemplateParameters(),
|
|
|
|
computation));
|
2013-02-16 08:17:33 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Look at all expansions in an expanded pack.
|
|
|
|
for (unsigned i = 0, n = TTP->getNumExpansionTemplateParameters();
|
|
|
|
i != n; ++i) {
|
|
|
|
LV.merge(getLVForTemplateParameterList(
|
2013-05-29 12:55:30 +08:00
|
|
|
TTP->getExpansionTemplateParameters(i), computation));
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-23 05:05:15 +08:00
|
|
|
return LV;
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
}
|
|
|
|
|
2013-01-12 14:42:30 +08:00
|
|
|
/// getLVForDecl - Get the linkage and visibility for the given declaration.
|
2013-02-16 08:17:33 +08:00
|
|
|
static LinkageInfo getLVForDecl(const NamedDecl *D,
|
|
|
|
LVComputationKind computation);
|
2010-12-07 02:36:25 +08:00
|
|
|
|
2013-07-02 04:22:57 +08:00
|
|
|
static const Decl *getOutermostFuncOrBlockContext(const Decl *D) {
|
2014-05-12 13:36:57 +08:00
|
|
|
const Decl *Ret = nullptr;
|
2013-05-16 12:30:21 +08:00
|
|
|
const DeclContext *DC = D->getDeclContext();
|
|
|
|
while (DC->getDeclKind() != Decl::TranslationUnit) {
|
2013-07-02 04:22:57 +08:00
|
|
|
if (isa<FunctionDecl>(DC) || isa<BlockDecl>(DC))
|
|
|
|
Ret = cast<Decl>(DC);
|
2013-05-16 12:30:21 +08:00
|
|
|
DC = DC->getParent();
|
|
|
|
}
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
/// \brief Get the most restrictive linkage for the types and
|
|
|
|
/// declarations in the given template argument list.
|
2013-02-16 08:17:33 +08:00
|
|
|
///
|
|
|
|
/// Note that we don't take an LVComputationKind because we always
|
|
|
|
/// want to honor the visibility of template arguments in the same way.
|
2014-04-23 13:16:48 +08:00
|
|
|
static LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
|
|
|
|
LVComputationKind computation) {
|
2013-02-16 08:17:33 +08:00
|
|
|
LinkageInfo LV;
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
|
2014-04-23 13:16:48 +08:00
|
|
|
for (const TemplateArgument &Arg : Args) {
|
|
|
|
switch (Arg.getKind()) {
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
case TemplateArgument::Null:
|
|
|
|
case TemplateArgument::Integral:
|
|
|
|
case TemplateArgument::Expression:
|
2013-02-16 08:17:33 +08:00
|
|
|
continue;
|
2012-01-02 14:26:22 +08:00
|
|
|
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
case TemplateArgument::Type:
|
2014-04-23 13:16:48 +08:00
|
|
|
LV.merge(getLVForType(*Arg.getAsType(), computation));
|
2013-02-16 08:17:33 +08:00
|
|
|
continue;
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
|
|
|
|
case TemplateArgument::Declaration:
|
2014-04-23 13:16:48 +08:00
|
|
|
if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl())) {
|
2013-02-16 08:17:33 +08:00
|
|
|
assert(!usesTypeVisibility(ND));
|
2013-05-29 12:55:30 +08:00
|
|
|
LV.merge(getLVForDecl(ND, computation));
|
2013-02-16 08:17:33 +08:00
|
|
|
}
|
|
|
|
continue;
|
2012-09-26 10:36:12 +08:00
|
|
|
|
|
|
|
case TemplateArgument::NullPtr:
|
2014-04-23 13:16:48 +08:00
|
|
|
LV.merge(Arg.getNullPtrType()->getLinkageAndVisibility());
|
2013-02-16 08:17:33 +08:00
|
|
|
continue;
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
|
|
|
|
case TemplateArgument::Template:
|
2011-01-06 02:58:31 +08:00
|
|
|
case TemplateArgument::TemplateExpansion:
|
2014-04-23 13:16:48 +08:00
|
|
|
if (TemplateDecl *Template =
|
|
|
|
Arg.getAsTemplateOrTemplatePattern().getAsTemplateDecl())
|
2013-05-29 12:55:30 +08:00
|
|
|
LV.merge(getLVForDecl(Template, computation));
|
2013-02-16 08:17:33 +08:00
|
|
|
continue;
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
|
|
|
|
case TemplateArgument::Pack:
|
2014-04-23 13:16:48 +08:00
|
|
|
LV.merge(getLVForTemplateArgumentList(Arg.getPackAsArray(), computation));
|
2013-02-16 08:17:33 +08:00
|
|
|
continue;
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
}
|
2013-02-16 08:17:33 +08:00
|
|
|
llvm_unreachable("bad template argument kind");
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
}
|
|
|
|
|
2010-10-23 05:05:15 +08:00
|
|
|
return LV;
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
}
|
|
|
|
|
2012-01-14 08:30:36 +08:00
|
|
|
static LinkageInfo
|
2013-05-29 12:55:30 +08:00
|
|
|
getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
|
|
|
|
LVComputationKind computation) {
|
|
|
|
return getLVForTemplateArgumentList(TArgs.asArray(), computation);
|
2010-08-13 16:35:10 +08:00
|
|
|
}
|
|
|
|
|
2013-02-22 07:42:58 +08:00
|
|
|
static bool shouldConsiderTemplateVisibility(const FunctionDecl *fn,
|
|
|
|
const FunctionTemplateSpecializationInfo *specInfo) {
|
|
|
|
// Include visibility from the template parameters and arguments
|
|
|
|
// only if this is not an explicit instantiation or specialization
|
|
|
|
// with direct explicit visibility. (Implicit instantiations won't
|
|
|
|
// have a direct attribute.)
|
|
|
|
if (!specInfo->isExplicitInstantiationOrSpecialization())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return !fn->hasAttr<VisibilityAttr>();
|
|
|
|
}
|
|
|
|
|
2013-02-16 08:17:33 +08:00
|
|
|
/// Merge in template-related linkage and visibility for the given
|
|
|
|
/// function template specialization.
|
|
|
|
///
|
|
|
|
/// We don't need a computation kind here because we can assume
|
|
|
|
/// LVForValue.
|
2013-02-22 07:42:58 +08:00
|
|
|
///
|
2013-02-22 12:06:28 +08:00
|
|
|
/// \param[out] LV the computation to use for the parent
|
2013-02-22 07:42:58 +08:00
|
|
|
static void
|
|
|
|
mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,
|
2013-05-29 12:55:30 +08:00
|
|
|
const FunctionTemplateSpecializationInfo *specInfo,
|
|
|
|
LVComputationKind computation) {
|
2013-02-22 07:42:58 +08:00
|
|
|
bool considerVisibility =
|
|
|
|
shouldConsiderTemplateVisibility(fn, specInfo);
|
2013-02-16 08:17:33 +08:00
|
|
|
|
|
|
|
// Merge information from the template parameters.
|
2013-02-22 07:42:58 +08:00
|
|
|
FunctionTemplateDecl *temp = specInfo->getTemplate();
|
2013-02-16 08:17:33 +08:00
|
|
|
LinkageInfo tempLV =
|
2013-05-29 12:55:30 +08:00
|
|
|
getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
|
2013-02-16 08:17:33 +08:00
|
|
|
LV.mergeMaybeWithVisibility(tempLV, considerVisibility);
|
|
|
|
|
|
|
|
// Merge information from the template arguments.
|
|
|
|
const TemplateArgumentList &templateArgs = *specInfo->TemplateArguments;
|
2013-05-29 12:55:30 +08:00
|
|
|
LinkageInfo argsLV = getLVForTemplateArgumentList(templateArgs, computation);
|
2013-02-16 08:17:33 +08:00
|
|
|
LV.mergeMaybeWithVisibility(argsLV, considerVisibility);
|
2011-06-28 07:06:04 +08:00
|
|
|
}
|
|
|
|
|
2013-02-22 07:42:58 +08:00
|
|
|
/// Does the given declaration have a direct visibility attribute
|
|
|
|
/// that would match the given rules?
|
|
|
|
static bool hasDirectVisibilityAttribute(const NamedDecl *D,
|
|
|
|
LVComputationKind computation) {
|
|
|
|
switch (computation) {
|
|
|
|
case LVForType:
|
|
|
|
case LVForExplicitType:
|
|
|
|
if (D->hasAttr<TypeVisibilityAttr>())
|
|
|
|
return true;
|
|
|
|
// fallthrough
|
|
|
|
case LVForValue:
|
|
|
|
case LVForExplicitValue:
|
|
|
|
if (D->hasAttr<VisibilityAttr>())
|
|
|
|
return true;
|
|
|
|
return false;
|
2013-05-29 03:43:11 +08:00
|
|
|
case LVForLinkageOnly:
|
|
|
|
return false;
|
2013-02-22 07:42:58 +08:00
|
|
|
}
|
|
|
|
llvm_unreachable("bad visibility computation kind");
|
|
|
|
}
|
|
|
|
|
2013-02-20 09:54:26 +08:00
|
|
|
/// Should we consider visibility associated with the template
|
|
|
|
/// arguments and parameters of the given class template specialization?
|
|
|
|
static bool shouldConsiderTemplateVisibility(
|
|
|
|
const ClassTemplateSpecializationDecl *spec,
|
|
|
|
LVComputationKind computation) {
|
2013-02-16 08:17:33 +08:00
|
|
|
// Include visibility from the template parameters and arguments
|
|
|
|
// only if this is not an explicit instantiation or specialization
|
|
|
|
// with direct explicit visibility (and note that implicit
|
|
|
|
// instantiations won't have a direct attribute).
|
|
|
|
//
|
|
|
|
// Furthermore, we want to ignore template parameters and arguments
|
2013-02-20 09:54:26 +08:00
|
|
|
// for an explicit specialization when computing the visibility of a
|
|
|
|
// member thereof with explicit visibility.
|
2013-02-16 08:17:33 +08:00
|
|
|
//
|
|
|
|
// This is a bit complex; let's unpack it.
|
|
|
|
//
|
|
|
|
// An explicit class specialization is an independent, top-level
|
|
|
|
// declaration. As such, if it or any of its members has an
|
|
|
|
// explicit visibility attribute, that must directly express the
|
|
|
|
// user's intent, and we should honor it. The same logic applies to
|
|
|
|
// an explicit instantiation of a member of such a thing.
|
2013-02-20 09:54:26 +08:00
|
|
|
|
|
|
|
// Fast path: if this is not an explicit instantiation or
|
|
|
|
// specialization, we always want to consider template-related
|
|
|
|
// visibility restrictions.
|
|
|
|
if (!spec->isExplicitInstantiationOrSpecialization())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// This is the 'member thereof' check.
|
|
|
|
if (spec->isExplicitSpecialization() &&
|
|
|
|
hasExplicitVisibilityAlready(computation))
|
|
|
|
return false;
|
|
|
|
|
2013-02-22 07:42:58 +08:00
|
|
|
return !hasDirectVisibilityAttribute(spec, computation);
|
2013-02-20 09:54:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Merge in template-related linkage and visibility for the given
|
|
|
|
/// class template specialization.
|
|
|
|
static void mergeTemplateLV(LinkageInfo &LV,
|
|
|
|
const ClassTemplateSpecializationDecl *spec,
|
|
|
|
LVComputationKind computation) {
|
|
|
|
bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation);
|
2013-02-16 08:17:33 +08:00
|
|
|
|
|
|
|
// Merge information from the template parameters, but ignore
|
|
|
|
// visibility if we're only considering template arguments.
|
|
|
|
|
2013-02-20 09:54:26 +08:00
|
|
|
ClassTemplateDecl *temp = spec->getSpecializedTemplate();
|
2013-02-16 08:17:33 +08:00
|
|
|
LinkageInfo tempLV =
|
2013-05-29 12:55:30 +08:00
|
|
|
getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
|
2013-02-16 08:17:33 +08:00
|
|
|
LV.mergeMaybeWithVisibility(tempLV,
|
2013-02-20 09:54:26 +08:00
|
|
|
considerVisibility && !hasExplicitVisibilityAlready(computation));
|
2013-02-16 08:17:33 +08:00
|
|
|
|
|
|
|
// Merge information from the template arguments. We ignore
|
|
|
|
// template-argument visibility if we've got an explicit
|
|
|
|
// instantiation with a visibility attribute.
|
|
|
|
const TemplateArgumentList &templateArgs = spec->getTemplateArgs();
|
2013-05-29 12:55:30 +08:00
|
|
|
LinkageInfo argsLV = getLVForTemplateArgumentList(templateArgs, computation);
|
2013-05-31 05:23:15 +08:00
|
|
|
if (considerVisibility)
|
|
|
|
LV.mergeVisibility(argsLV);
|
|
|
|
LV.mergeExternalVisibility(argsLV);
|
2011-06-28 07:06:04 +08:00
|
|
|
}
|
|
|
|
|
2014-07-03 07:08:34 +08:00
|
|
|
/// Should we consider visibility associated with the template
|
|
|
|
/// arguments and parameters of the given variable template
|
|
|
|
/// specialization? As usual, follow class template specialization
|
|
|
|
/// logic up to initialization.
|
|
|
|
static bool shouldConsiderTemplateVisibility(
|
|
|
|
const VarTemplateSpecializationDecl *spec,
|
|
|
|
LVComputationKind computation) {
|
|
|
|
// Include visibility from the template parameters and arguments
|
|
|
|
// only if this is not an explicit instantiation or specialization
|
|
|
|
// with direct explicit visibility (and note that implicit
|
|
|
|
// instantiations won't have a direct attribute).
|
|
|
|
if (!spec->isExplicitInstantiationOrSpecialization())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// An explicit variable specialization is an independent, top-level
|
|
|
|
// declaration. As such, if it has an explicit visibility attribute,
|
|
|
|
// that must directly express the user's intent, and we should honor
|
|
|
|
// it.
|
|
|
|
if (spec->isExplicitSpecialization() &&
|
|
|
|
hasExplicitVisibilityAlready(computation))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return !hasDirectVisibilityAttribute(spec, computation);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Merge in template-related linkage and visibility for the given
|
|
|
|
/// variable template specialization. As usual, follow class template
|
|
|
|
/// specialization logic up to initialization.
|
|
|
|
static void mergeTemplateLV(LinkageInfo &LV,
|
|
|
|
const VarTemplateSpecializationDecl *spec,
|
|
|
|
LVComputationKind computation) {
|
|
|
|
bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation);
|
|
|
|
|
|
|
|
// Merge information from the template parameters, but ignore
|
|
|
|
// visibility if we're only considering template arguments.
|
|
|
|
|
|
|
|
VarTemplateDecl *temp = spec->getSpecializedTemplate();
|
|
|
|
LinkageInfo tempLV =
|
|
|
|
getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
|
|
|
|
LV.mergeMaybeWithVisibility(tempLV,
|
|
|
|
considerVisibility && !hasExplicitVisibilityAlready(computation));
|
|
|
|
|
|
|
|
// Merge information from the template arguments. We ignore
|
|
|
|
// template-argument visibility if we've got an explicit
|
|
|
|
// instantiation with a visibility attribute.
|
|
|
|
const TemplateArgumentList &templateArgs = spec->getTemplateArgs();
|
|
|
|
LinkageInfo argsLV = getLVForTemplateArgumentList(templateArgs, computation);
|
|
|
|
if (considerVisibility)
|
|
|
|
LV.mergeVisibility(argsLV);
|
|
|
|
LV.mergeExternalVisibility(argsLV);
|
|
|
|
}
|
|
|
|
|
2012-07-13 22:25:36 +08:00
|
|
|
static bool useInlineVisibilityHidden(const NamedDecl *D) {
|
|
|
|
// FIXME: we should warn if -fvisibility-inlines-hidden is used with c.
|
2012-07-14 07:26:43 +08:00
|
|
|
const LangOptions &Opts = D->getASTContext().getLangOpts();
|
|
|
|
if (!Opts.CPlusPlus || !Opts.InlineVisibilityHidden)
|
2012-07-13 22:25:36 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
|
|
|
|
if (!FD)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
TemplateSpecializationKind TSK = TSK_Undeclared;
|
|
|
|
if (FunctionTemplateSpecializationInfo *spec
|
|
|
|
= FD->getTemplateSpecializationInfo()) {
|
|
|
|
TSK = spec->getTemplateSpecializationKind();
|
|
|
|
} else if (MemberSpecializationInfo *MSI =
|
|
|
|
FD->getMemberSpecializationInfo()) {
|
|
|
|
TSK = MSI->getTemplateSpecializationKind();
|
|
|
|
}
|
|
|
|
|
2014-05-12 13:36:57 +08:00
|
|
|
const FunctionDecl *Def = nullptr;
|
2012-07-13 22:25:36 +08:00
|
|
|
// InlineVisibilityHidden only applies to definitions, and
|
|
|
|
// isInlined() only gives meaningful answers on definitions
|
|
|
|
// anyway.
|
|
|
|
return TSK != TSK_ExplicitInstantiationDeclaration &&
|
|
|
|
TSK != TSK_ExplicitInstantiationDefinition &&
|
2012-10-12 00:32:25 +08:00
|
|
|
FD->hasBody(Def) && Def->isInlined() && !Def->hasAttr<GNUInlineAttr>();
|
2012-07-13 22:25:36 +08:00
|
|
|
}
|
|
|
|
|
2013-05-06 04:15:21 +08:00
|
|
|
template <typename T> static bool isFirstInExternCContext(T *D) {
|
2013-10-17 23:37:26 +08:00
|
|
|
const T *First = D->getFirstDecl();
|
2013-05-06 04:15:21 +08:00
|
|
|
return First->isInExternCContext();
|
2013-02-14 09:18:37 +08:00
|
|
|
}
|
|
|
|
|
2014-02-18 07:34:47 +08:00
|
|
|
static bool isSingleLineLanguageLinkage(const Decl &D) {
|
2013-04-26 09:30:23 +08:00
|
|
|
if (const LinkageSpecDecl *SD = dyn_cast<LinkageSpecDecl>(D.getDeclContext()))
|
2014-02-18 07:34:47 +08:00
|
|
|
if (!SD->hasBraces())
|
2013-04-26 09:30:23 +08:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-04-22 07:28:21 +08:00
|
|
|
static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
|
2013-02-16 08:17:33 +08:00
|
|
|
LVComputationKind computation) {
|
2010-08-31 08:36:30 +08:00
|
|
|
assert(D->getDeclContext()->getRedeclContext()->isFileContext() &&
|
2009-11-26 06:24:25 +08:00
|
|
|
"Not a name having namespace scope");
|
|
|
|
ASTContext &Context = D->getASTContext();
|
|
|
|
|
|
|
|
// C++ [basic.link]p3:
|
|
|
|
// A name having namespace scope (3.3.6) has internal linkage if it
|
|
|
|
// is the name of
|
|
|
|
// - an object, reference, function or function template that is
|
|
|
|
// explicitly declared static; or,
|
|
|
|
// (This bullet corresponds to C99 6.2.2p3.)
|
|
|
|
if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
|
|
|
|
// Explicitly declared static.
|
2010-08-26 11:08:43 +08:00
|
|
|
if (Var->getStorageClass() == SC_Static)
|
2010-10-30 19:50:40 +08:00
|
|
|
return LinkageInfo::internal();
|
2009-11-26 06:24:25 +08:00
|
|
|
|
2012-10-19 14:37:48 +08:00
|
|
|
// - a non-volatile object or reference that is explicitly declared const
|
|
|
|
// or constexpr and neither explicitly declared extern nor previously
|
|
|
|
// declared to have external linkage; or (there is no equivalent in C99)
|
2012-03-11 15:00:24 +08:00
|
|
|
if (Context.getLangOpts().CPlusPlus &&
|
2012-10-19 14:37:48 +08:00
|
|
|
Var->getType().isConstQualified() &&
|
2013-04-04 03:27:57 +08:00
|
|
|
!Var->getType().isVolatileQualified()) {
|
2013-04-04 03:22:20 +08:00
|
|
|
const VarDecl *PrevVar = Var->getPreviousDecl();
|
|
|
|
if (PrevVar)
|
2013-05-29 12:55:30 +08:00
|
|
|
return getLVForDecl(PrevVar, computation);
|
2013-04-04 03:27:57 +08:00
|
|
|
|
|
|
|
if (Var->getStorageClass() != SC_Extern &&
|
2013-04-26 09:30:23 +08:00
|
|
|
Var->getStorageClass() != SC_PrivateExtern &&
|
2014-02-18 07:34:47 +08:00
|
|
|
!isSingleLineLanguageLinkage(*Var))
|
2013-04-04 03:27:57 +08:00
|
|
|
return LinkageInfo::internal();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const VarDecl *PrevVar = Var->getPreviousDecl(); PrevVar;
|
|
|
|
PrevVar = PrevVar->getPreviousDecl()) {
|
|
|
|
if (PrevVar->getStorageClass() == SC_PrivateExtern &&
|
|
|
|
Var->getStorageClass() == SC_None)
|
|
|
|
return PrevVar->getLinkageAndVisibility();
|
|
|
|
// Explicitly declared static.
|
|
|
|
if (PrevVar->getStorageClass() == SC_Static)
|
|
|
|
return LinkageInfo::internal();
|
2011-06-17 04:14:50 +08:00
|
|
|
}
|
2014-01-22 15:29:52 +08:00
|
|
|
} else if (const FunctionDecl *Function = D->getAsFunction()) {
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
// C++ [temp]p4:
|
|
|
|
// A non-member function template can have internal linkage; any
|
|
|
|
// other template name shall have external linkage.
|
2009-11-26 06:24:25 +08:00
|
|
|
|
|
|
|
// Explicitly declared static.
|
2013-04-04 03:27:57 +08:00
|
|
|
if (Function->getCanonicalDecl()->getStorageClass() == SC_Static)
|
2010-10-30 19:50:40 +08:00
|
|
|
return LinkageInfo(InternalLinkage, DefaultVisibility, false);
|
2014-12-11 06:58:14 +08:00
|
|
|
} else if (const auto *IFD = dyn_cast<IndirectFieldDecl>(D)) {
|
|
|
|
// - a data member of an anonymous union.
|
|
|
|
const VarDecl *VD = IFD->getVarDecl();
|
|
|
|
assert(VD && "Expected a VarDecl in this IndirectFieldDecl!");
|
|
|
|
return getLVForNamespaceScopeDecl(VD, computation);
|
2009-11-26 06:24:25 +08:00
|
|
|
}
|
2013-10-24 04:52:43 +08:00
|
|
|
assert(!isa<FieldDecl>(D) && "Didn't expect a FieldDecl!");
|
2009-11-26 06:24:25 +08:00
|
|
|
|
2011-02-25 03:03:39 +08:00
|
|
|
if (D->isInAnonymousNamespace()) {
|
|
|
|
const VarDecl *Var = dyn_cast<VarDecl>(D);
|
|
|
|
const FunctionDecl *Func = dyn_cast<FunctionDecl>(D);
|
2013-05-06 04:15:21 +08:00
|
|
|
if ((!Var || !isFirstInExternCContext(Var)) &&
|
|
|
|
(!Func || !isFirstInExternCContext(Func)))
|
2011-02-25 03:03:39 +08:00
|
|
|
return LinkageInfo::uniqueExternal();
|
|
|
|
}
|
2010-10-28 12:18:25 +08:00
|
|
|
|
2010-10-23 05:05:15 +08:00
|
|
|
// Set up the defaults.
|
|
|
|
|
|
|
|
// C99 6.2.2p5:
|
|
|
|
// If the declaration of an identifier for an object has file
|
|
|
|
// scope and no storage-class specifier, its linkage is
|
|
|
|
// external.
|
2010-10-30 19:50:40 +08:00
|
|
|
LinkageInfo LV;
|
|
|
|
|
2013-02-20 09:54:26 +08:00
|
|
|
if (!hasExplicitVisibilityAlready(computation)) {
|
2013-02-21 06:23:23 +08:00
|
|
|
if (Optional<Visibility> Vis = getExplicitVisibility(D, computation)) {
|
2012-04-19 10:22:07 +08:00
|
|
|
LV.mergeVisibility(*Vis, true);
|
2012-04-17 02:46:26 +08:00
|
|
|
} else {
|
|
|
|
// If we're declared in a namespace with a visibility attribute,
|
2013-02-16 08:17:33 +08:00
|
|
|
// use that namespace's visibility, and it still counts as explicit.
|
2012-04-17 02:46:26 +08:00
|
|
|
for (const DeclContext *DC = D->getDeclContext();
|
|
|
|
!isa<TranslationUnitDecl>(DC);
|
|
|
|
DC = DC->getParent()) {
|
|
|
|
const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC);
|
|
|
|
if (!ND) continue;
|
2013-02-21 06:23:23 +08:00
|
|
|
if (Optional<Visibility> Vis = getExplicitVisibility(ND, computation)) {
|
2012-04-19 10:22:07 +08:00
|
|
|
LV.mergeVisibility(*Vis, true);
|
2012-04-17 02:46:26 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-16 08:17:33 +08:00
|
|
|
// Add in global settings if the above didn't give us direct visibility.
|
2013-02-27 10:56:45 +08:00
|
|
|
if (!LV.isVisibilityExplicit()) {
|
2013-02-19 09:57:35 +08:00
|
|
|
// Use global type/value visibility as appropriate.
|
|
|
|
Visibility globalVisibility;
|
|
|
|
if (computation == LVForValue) {
|
2015-02-04 10:34:32 +08:00
|
|
|
globalVisibility = Context.getLangOpts().getValueVisibilityMode();
|
2013-02-19 09:57:35 +08:00
|
|
|
} else {
|
|
|
|
assert(computation == LVForType);
|
|
|
|
globalVisibility = Context.getLangOpts().getTypeVisibilityMode();
|
|
|
|
}
|
|
|
|
LV.mergeVisibility(globalVisibility, /*explicit*/ false);
|
2013-02-16 08:17:33 +08:00
|
|
|
|
|
|
|
// If we're paying attention to global visibility, apply
|
|
|
|
// -finline-visibility-hidden if this is an inline method.
|
|
|
|
if (useInlineVisibilityHidden(D))
|
|
|
|
LV.mergeVisibility(HiddenVisibility, true);
|
|
|
|
}
|
2012-07-13 22:25:36 +08:00
|
|
|
}
|
2012-04-19 10:55:01 +08:00
|
|
|
|
2009-11-26 06:24:25 +08:00
|
|
|
// C++ [basic.link]p4:
|
2010-10-23 05:05:15 +08:00
|
|
|
|
2009-11-26 06:24:25 +08:00
|
|
|
// A name having namespace scope has external linkage if it is the
|
|
|
|
// name of
|
|
|
|
//
|
|
|
|
// - an object or reference, unless it has internal linkage; or
|
|
|
|
if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
|
2010-10-30 06:22:43 +08:00
|
|
|
// GCC applies the following optimization to variables and static
|
|
|
|
// data members, but not to functions:
|
|
|
|
//
|
2010-10-23 05:05:15 +08:00
|
|
|
// Modify the variable's LV by the LV of its type unless this is
|
|
|
|
// C or extern "C". This follows from [basic.link]p9:
|
|
|
|
// A type without linkage shall not be used as the type of a
|
|
|
|
// variable or function with external linkage unless
|
|
|
|
// - the entity has C language linkage, or
|
|
|
|
// - the entity is declared within an unnamed namespace, or
|
|
|
|
// - the entity is not used or is defined in the same
|
|
|
|
// translation unit.
|
|
|
|
// and [basic.link]p10:
|
|
|
|
// ...the types specified by all declarations referring to a
|
|
|
|
// given variable or function shall be identical...
|
|
|
|
// C does not have an equivalent rule.
|
|
|
|
//
|
2010-10-26 12:59:26 +08:00
|
|
|
// Ignore this if we've got an explicit attribute; the user
|
|
|
|
// probably knows what they're doing.
|
|
|
|
//
|
2010-10-23 05:05:15 +08:00
|
|
|
// Note that we don't want to make the variable non-external
|
|
|
|
// because of this, but unique-external linkage suits us.
|
2013-05-06 04:15:21 +08:00
|
|
|
if (Context.getLangOpts().CPlusPlus && !isFirstInExternCContext(Var)) {
|
2013-05-29 12:55:30 +08:00
|
|
|
LinkageInfo TypeLV = getLVForType(*Var->getType(), computation);
|
2013-02-27 10:56:45 +08:00
|
|
|
if (TypeLV.getLinkage() != ExternalLinkage)
|
2010-10-30 19:50:40 +08:00
|
|
|
return LinkageInfo::uniqueExternal();
|
2013-02-27 10:56:45 +08:00
|
|
|
if (!LV.isVisibilityExplicit())
|
2013-02-16 08:17:33 +08:00
|
|
|
LV.mergeVisibility(TypeLV);
|
2010-10-30 06:22:43 +08:00
|
|
|
}
|
|
|
|
|
2010-11-03 02:38:13 +08:00
|
|
|
if (Var->getStorageClass() == SC_PrivateExtern)
|
2012-04-19 10:22:07 +08:00
|
|
|
LV.mergeVisibility(HiddenVisibility, true);
|
2010-11-03 02:38:13 +08:00
|
|
|
|
2012-11-12 12:10:23 +08:00
|
|
|
// Note that Sema::MergeVarDecl already takes care of implementing
|
|
|
|
// C99 6.2.2p4 and propagating the visibility attribute, so we don't have
|
|
|
|
// to do it here.
|
2009-11-26 06:24:25 +08:00
|
|
|
|
2014-07-03 07:08:34 +08:00
|
|
|
// As per function and class template specializations (below),
|
|
|
|
// consider LV for the template and template arguments. We're at file
|
|
|
|
// scope, so we do not need to worry about nested specializations.
|
|
|
|
if (const VarTemplateSpecializationDecl *spec
|
|
|
|
= dyn_cast<VarTemplateSpecializationDecl>(Var)) {
|
|
|
|
mergeTemplateLV(LV, spec, computation);
|
|
|
|
}
|
|
|
|
|
2009-11-26 06:24:25 +08:00
|
|
|
// - a function, unless it has internal linkage; or
|
2010-10-23 05:05:15 +08:00
|
|
|
} else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
|
2010-10-28 15:07:52 +08:00
|
|
|
// In theory, we can modify the function's LV by the LV of its
|
|
|
|
// type unless it has C linkage (see comment above about variables
|
|
|
|
// for justification). In practice, GCC doesn't do this, so it's
|
|
|
|
// just too painful to make work.
|
2010-10-23 05:05:15 +08:00
|
|
|
|
2010-11-03 02:38:13 +08:00
|
|
|
if (Function->getStorageClass() == SC_PrivateExtern)
|
2012-04-19 10:22:07 +08:00
|
|
|
LV.mergeVisibility(HiddenVisibility, true);
|
2010-11-03 02:38:13 +08:00
|
|
|
|
2012-11-21 10:47:19 +08:00
|
|
|
// Note that Sema::MergeCompatibleFunctionDecls already takes care of
|
|
|
|
// merging storage classes and visibility attributes, so we don't have to
|
|
|
|
// look at previous decls in here.
|
2009-11-26 06:24:25 +08:00
|
|
|
|
2011-02-10 14:50:24 +08:00
|
|
|
// In C++, then if the type of the function uses a type with
|
|
|
|
// unique-external linkage, it's not legally usable from outside
|
|
|
|
// this translation unit. However, we should use the C linkage
|
|
|
|
// rules instead for extern "C" declarations.
|
2012-03-11 15:00:24 +08:00
|
|
|
if (Context.getLangOpts().CPlusPlus &&
|
2013-05-13 07:17:59 +08:00
|
|
|
!Function->isInExternCContext()) {
|
|
|
|
// Only look at the type-as-written. If this function has an auto-deduced
|
|
|
|
// return type, we can't compute the linkage of that type because it could
|
|
|
|
// require looking at the linkage of this function, and we don't need this
|
|
|
|
// for correctness because the type is not part of the function's
|
|
|
|
// signature.
|
2013-10-08 12:15:04 +08:00
|
|
|
// FIXME: This is a hack. We should be able to solve this circularity and
|
|
|
|
// the one in getLVForClassMember for Functions some other way.
|
2013-05-13 07:17:59 +08:00
|
|
|
QualType TypeAsWritten = Function->getType();
|
|
|
|
if (TypeSourceInfo *TSI = Function->getTypeSourceInfo())
|
|
|
|
TypeAsWritten = TSI->getType();
|
|
|
|
if (TypeAsWritten->getLinkage() == UniqueExternalLinkage)
|
|
|
|
return LinkageInfo::uniqueExternal();
|
|
|
|
}
|
2011-02-10 14:50:24 +08:00
|
|
|
|
2013-02-22 07:42:58 +08:00
|
|
|
// Consider LV from the template and the template arguments.
|
|
|
|
// We're at file scope, so we do not need to worry about nested
|
|
|
|
// specializations.
|
2011-06-28 07:06:04 +08:00
|
|
|
if (FunctionTemplateSpecializationInfo *specInfo
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
= Function->getTemplateSpecializationInfo()) {
|
2013-05-29 12:55:30 +08:00
|
|
|
mergeTemplateLV(LV, Function, specInfo, computation);
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
}
|
|
|
|
|
2009-11-26 06:24:25 +08:00
|
|
|
// - a named class (Clause 9), or an unnamed class defined in a
|
|
|
|
// typedef declaration in which the class has the typedef name
|
|
|
|
// for linkage purposes (7.1.3); or
|
|
|
|
// - a named enumeration (7.2), or an unnamed enumeration
|
|
|
|
// defined in a typedef declaration in which the enumeration
|
|
|
|
// has the typedef name for linkage purposes (7.1.3); or
|
2010-10-23 05:05:15 +08:00
|
|
|
} else if (const TagDecl *Tag = dyn_cast<TagDecl>(D)) {
|
|
|
|
// Unnamed tags have no linkage.
|
2013-03-09 08:54:27 +08:00
|
|
|
if (!Tag->hasNameForLinkage())
|
2010-10-30 19:50:40 +08:00
|
|
|
return LinkageInfo::none();
|
2010-10-23 05:05:15 +08:00
|
|
|
|
|
|
|
// If this is a class template specialization, consider the
|
2013-02-22 07:42:58 +08:00
|
|
|
// linkage of the template and template arguments. We're at file
|
|
|
|
// scope, so we do not need to worry about nested specializations.
|
2011-06-28 07:06:04 +08:00
|
|
|
if (const ClassTemplateSpecializationDecl *spec
|
2010-10-23 05:05:15 +08:00
|
|
|
= dyn_cast<ClassTemplateSpecializationDecl>(Tag)) {
|
2013-02-16 08:17:33 +08:00
|
|
|
mergeTemplateLV(LV, spec, computation);
|
When a function or variable somehow depends on a type or declaration
that is in an anonymous namespace, give that function or variable
internal linkage.
This change models an oddity of the C++ standard, where names declared
in an anonymous namespace have external linkage but, because anonymous
namespace are really "uniquely-named" namespaces, the names cannot be
referenced from other translation units. That means that they have
external linkage for semantic analysis, but the only sensible
implementation for code generation is to give them internal
linkage. We now model this notion via the UniqueExternalLinkage
linkage type. There are several changes here:
- Extended NamedDecl::getLinkage() to produce UniqueExternalLinkage
when the declaration is in an anonymous namespace.
- Added Type::getLinkage() to determine the linkage of a type, which
is defined as the minimum linkage of the types (when we're dealing
with a compound type that is not a struct/class/union).
- Extended NamedDecl::getLinkage() to consider the linkage of the
template arguments and template parameters of function template
specializations and class template specializations.
- Taught code generation to rely on NamedDecl::getLinkage() when
determining the linkage of variables and functions, also
considering the linkage of the types of those variables and
functions (C++ only). Map UniqueExternalLinkage to internal
linkage, taking out the explicit checks for
isInAnonymousNamespace().
This fixes much of PR5792, which, as discovered by Anders Carlsson, is
actually the reason behind the pass-manager assertion that causes the
majority of clang-on-clang regression test failures. With this fix,
Clang-built-Clang+LLVM passes 88% of its regression tests (up from
67%). The specific numbers are:
LLVM:
Expected Passes : 4006
Expected Failures : 32
Unsupported Tests : 40
Unexpected Failures: 736
Clang:
Expected Passes : 1903
Expected Failures : 14
Unexpected Failures: 75
Overall:
Expected Passes : 5909
Expected Failures : 46
Unsupported Tests : 40
Unexpected Failures: 811
Still to do:
- Improve testing
- Check whether we should allow the presence of types with
InternalLinkage (in addition to UniqueExternalLinkage) given
variables/functions internal linkage in C++, as mentioned in
PR5792.
- Determine how expensive the getLinkage() calls are in practice;
consider caching the result in NamedDecl.
- Assess the feasibility of Chris's idea in comment #1 of PR5792.
llvm-svn: 95216
2010-02-03 17:33:45 +08:00
|
|
|
}
|
2009-11-26 06:24:25 +08:00
|
|
|
|
|
|
|
// - an enumerator belonging to an enumeration with external linkage;
|
2010-10-23 05:05:15 +08:00
|
|
|
} else if (isa<EnumConstantDecl>(D)) {
|
2012-04-22 07:28:21 +08:00
|
|
|
LinkageInfo EnumLV = getLVForDecl(cast<NamedDecl>(D->getDeclContext()),
|
2013-02-16 08:17:33 +08:00
|
|
|
computation);
|
2013-05-27 22:14:42 +08:00
|
|
|
if (!isExternalFormalLinkage(EnumLV.getLinkage()))
|
2010-10-30 19:50:40 +08:00
|
|
|
return LinkageInfo::none();
|
|
|
|
LV.merge(EnumLV);
|
2009-11-26 06:24:25 +08:00
|
|
|
|
|
|
|
// - a template, unless it is a function template that has
|
|
|
|
// internal linkage (Clause 14);
|
2011-03-04 18:39:25 +08:00
|
|
|
} else if (const TemplateDecl *temp = dyn_cast<TemplateDecl>(D)) {
|
2013-02-20 09:54:26 +08:00
|
|
|
bool considerVisibility = !hasExplicitVisibilityAlready(computation);
|
2013-02-16 08:17:33 +08:00
|
|
|
LinkageInfo tempLV =
|
2013-05-29 12:55:30 +08:00
|
|
|
getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
|
2013-02-16 08:17:33 +08:00
|
|
|
LV.mergeMaybeWithVisibility(tempLV, considerVisibility);
|
|
|
|
|
2009-11-26 06:24:25 +08:00
|
|
|
// - a namespace (7.3), unless it is declared within an unnamed
|
|
|
|
// namespace.
|
2010-10-23 05:05:15 +08:00
|
|
|
} else if (isa<NamespaceDecl>(D) && !D->isInAnonymousNamespace()) {
|
|
|
|
return LV;
|
|
|
|
|
|
|
|
// By extension, we assign external linkage to Objective-C
|
|
|
|
// interfaces.
|
|
|
|
} else if (isa<ObjCInterfaceDecl>(D)) {
|
|
|
|
// fallout
|
|
|
|
|
|
|
|
// Everything not covered here has no linkage.
|
|
|
|
} else {
|
2014-08-12 02:35:44 +08:00
|
|
|
// FIXME: A typedef declaration has linkage if it gives a type a name for
|
|
|
|
// linkage purposes.
|
2010-10-30 19:50:40 +08:00
|
|
|
return LinkageInfo::none();
|
2010-10-23 05:05:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// If we ended up with non-external linkage, visibility should
|
|
|
|
// always be default.
|
2013-02-27 10:56:45 +08:00
|
|
|
if (LV.getLinkage() != ExternalLinkage)
|
|
|
|
return LinkageInfo(LV.getLinkage(), DefaultVisibility, false);
|
2010-10-23 05:05:15 +08:00
|
|
|
|
|
|
|
return LV;
|
2009-11-26 06:24:25 +08:00
|
|
|
}
|
|
|
|
|
2013-02-16 08:17:33 +08:00
|
|
|
static LinkageInfo getLVForClassMember(const NamedDecl *D,
|
|
|
|
LVComputationKind computation) {
|
2010-10-23 05:05:15 +08:00
|
|
|
// Only certain class members have linkage. Note that fields don't
|
|
|
|
// really have linkage, but it's convenient to say they do for the
|
|
|
|
// purposes of calculating linkage of pointer-to-data-member
|
|
|
|
// template arguments.
|
2014-01-08 09:51:59 +08:00
|
|
|
//
|
|
|
|
// Templates also don't officially have linkage, but since we ignore
|
|
|
|
// the C++ standard and look at template arguments when determining
|
|
|
|
// linkage and visibility of a template specialization, we might hit
|
|
|
|
// a template template argument that way. If we do, we need to
|
|
|
|
// consider its linkage.
|
2010-08-13 16:35:10 +08:00
|
|
|
if (!(isa<CXXMethodDecl>(D) ||
|
|
|
|
isa<VarDecl>(D) ||
|
2010-10-23 05:05:15 +08:00
|
|
|
isa<FieldDecl>(D) ||
|
2013-10-24 04:52:43 +08:00
|
|
|
isa<IndirectFieldDecl>(D) ||
|
2014-01-08 09:51:59 +08:00
|
|
|
isa<TagDecl>(D) ||
|
|
|
|
isa<TemplateDecl>(D)))
|
2010-10-30 19:50:40 +08:00
|
|
|
return LinkageInfo::none();
|
2010-08-13 16:35:10 +08:00
|
|
|
|
2010-11-02 09:45:15 +08:00
|
|
|
LinkageInfo LV;
|
|
|
|
|
|
|
|
// If we have an explicit visibility attribute, merge that in.
|
2013-02-20 09:54:26 +08:00
|
|
|
if (!hasExplicitVisibilityAlready(computation)) {
|
2013-02-21 06:23:23 +08:00
|
|
|
if (Optional<Visibility> Vis = getExplicitVisibility(D, computation))
|
2011-03-26 20:10:19 +08:00
|
|
|
LV.mergeVisibility(*Vis, true);
|
2012-07-13 22:25:36 +08:00
|
|
|
// If we're paying attention to global visibility, apply
|
|
|
|
// -finline-visibility-hidden if this is an inline method.
|
|
|
|
//
|
|
|
|
// Note that we do this before merging information about
|
|
|
|
// the class visibility.
|
2013-02-27 10:56:45 +08:00
|
|
|
if (!LV.isVisibilityExplicit() && useInlineVisibilityHidden(D))
|
2012-07-13 22:25:36 +08:00
|
|
|
LV.mergeVisibility(HiddenVisibility, true);
|
2012-04-17 02:25:01 +08:00
|
|
|
}
|
2012-04-19 13:50:08 +08:00
|
|
|
|
|
|
|
// If this class member has an explicit visibility attribute, the only
|
|
|
|
// thing that can change its visibility is the template arguments, so
|
2012-07-23 16:59:39 +08:00
|
|
|
// only look for them when processing the class.
|
2013-02-20 09:54:26 +08:00
|
|
|
LVComputationKind classComputation = computation;
|
2013-02-27 10:56:45 +08:00
|
|
|
if (LV.isVisibilityExplicit())
|
2013-02-20 09:54:26 +08:00
|
|
|
classComputation = withExplicitVisibilityAlready(computation);
|
2010-11-02 09:45:15 +08:00
|
|
|
|
2013-02-22 07:42:58 +08:00
|
|
|
LinkageInfo classLV =
|
|
|
|
getLVForDecl(cast<RecordDecl>(D->getDeclContext()), classComputation);
|
2010-08-13 16:35:10 +08:00
|
|
|
// If the class already has unique-external linkage, we can't improve.
|
2013-02-27 10:56:45 +08:00
|
|
|
if (classLV.getLinkage() == UniqueExternalLinkage)
|
2010-10-30 19:50:40 +08:00
|
|
|
return LinkageInfo::uniqueExternal();
|
2010-10-23 05:05:15 +08:00
|
|
|
|
2013-05-28 10:22:10 +08:00
|
|
|
if (!isExternallyVisible(classLV.getLinkage()))
|
|
|
|
return LinkageInfo::none();
|
|
|
|
|
|
|
|
|
2013-02-22 07:42:58 +08:00
|
|
|
// Otherwise, don't merge in classLV yet, because in certain cases
|
|
|
|
// we need to completely ignore the visibility from it.
|
|
|
|
|
|
|
|
// Specifically, if this decl exists and has an explicit attribute.
|
2014-05-12 13:36:57 +08:00
|
|
|
const NamedDecl *explicitSpecSuppressor = nullptr;
|
2013-02-22 07:42:58 +08:00
|
|
|
|
2010-08-13 16:35:10 +08:00
|
|
|
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
|
2011-02-10 14:50:24 +08:00
|
|
|
// If the type of the function uses a type with unique-external
|
|
|
|
// linkage, it's not legally usable from outside this translation unit.
|
2013-10-08 12:15:04 +08:00
|
|
|
// But only look at the type-as-written. If this function has an auto-deduced
|
|
|
|
// return type, we can't compute the linkage of that type because it could
|
|
|
|
// require looking at the linkage of this function, and we don't need this
|
|
|
|
// for correctness because the type is not part of the function's
|
|
|
|
// signature.
|
|
|
|
// FIXME: This is a hack. We should be able to solve this circularity and the
|
|
|
|
// one in getLVForNamespaceScopeDecl for Functions some other way.
|
|
|
|
{
|
|
|
|
QualType TypeAsWritten = MD->getType();
|
|
|
|
if (TypeSourceInfo *TSI = MD->getTypeSourceInfo())
|
|
|
|
TypeAsWritten = TSI->getType();
|
|
|
|
if (TypeAsWritten->getLinkage() == UniqueExternalLinkage)
|
|
|
|
return LinkageInfo::uniqueExternal();
|
|
|
|
}
|
2010-10-23 05:05:15 +08:00
|
|
|
// If this is a method template specialization, use the linkage for
|
|
|
|
// the template parameters and arguments.
|
2011-06-28 07:06:04 +08:00
|
|
|
if (FunctionTemplateSpecializationInfo *spec
|
2010-08-13 16:35:10 +08:00
|
|
|
= MD->getTemplateSpecializationInfo()) {
|
2013-05-29 12:55:30 +08:00
|
|
|
mergeTemplateLV(LV, MD, spec, computation);
|
2013-02-22 07:42:58 +08:00
|
|
|
if (spec->isExplicitSpecialization()) {
|
|
|
|
explicitSpecSuppressor = MD;
|
|
|
|
} else if (isExplicitMemberSpecialization(spec->getTemplate())) {
|
|
|
|
explicitSpecSuppressor = spec->getTemplate()->getTemplatedDecl();
|
|
|
|
}
|
|
|
|
} else if (isExplicitMemberSpecialization(MD)) {
|
|
|
|
explicitSpecSuppressor = MD;
|
2010-11-01 09:29:57 +08:00
|
|
|
}
|
2010-10-23 05:05:15 +08:00
|
|
|
|
2010-10-30 06:22:43 +08:00
|
|
|
} else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
|
2011-06-28 07:06:04 +08:00
|
|
|
if (const ClassTemplateSpecializationDecl *spec
|
2010-10-30 06:22:43 +08:00
|
|
|
= dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
|
2013-02-16 08:17:33 +08:00
|
|
|
mergeTemplateLV(LV, spec, computation);
|
2013-02-22 07:42:58 +08:00
|
|
|
if (spec->isExplicitSpecialization()) {
|
|
|
|
explicitSpecSuppressor = spec;
|
|
|
|
} else {
|
|
|
|
const ClassTemplateDecl *temp = spec->getSpecializedTemplate();
|
|
|
|
if (isExplicitMemberSpecialization(temp)) {
|
|
|
|
explicitSpecSuppressor = temp->getTemplatedDecl();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (isExplicitMemberSpecialization(RD)) {
|
|
|
|
explicitSpecSuppressor = RD;
|
2010-10-30 06:22:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Static data members.
|
|
|
|
} else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
|
2014-07-03 07:08:34 +08:00
|
|
|
if (const VarTemplateSpecializationDecl *spec
|
|
|
|
= dyn_cast<VarTemplateSpecializationDecl>(VD))
|
|
|
|
mergeTemplateLV(LV, spec, computation);
|
|
|
|
|
2010-10-30 17:18:49 +08:00
|
|
|
// Modify the variable's linkage by its type, but ignore the
|
|
|
|
// type's visibility unless it's a definition.
|
2013-05-29 12:55:30 +08:00
|
|
|
LinkageInfo typeLV = getLVForType(*VD->getType(), computation);
|
2013-05-31 05:23:15 +08:00
|
|
|
if (!LV.isVisibilityExplicit() && !classLV.isVisibilityExplicit())
|
|
|
|
LV.mergeVisibility(typeLV);
|
|
|
|
LV.mergeExternalVisibility(typeLV);
|
2013-02-22 07:42:58 +08:00
|
|
|
|
|
|
|
if (isExplicitMemberSpecialization(VD)) {
|
|
|
|
explicitSpecSuppressor = VD;
|
|
|
|
}
|
2013-02-16 08:17:33 +08:00
|
|
|
|
|
|
|
// Template members.
|
|
|
|
} else if (const TemplateDecl *temp = dyn_cast<TemplateDecl>(D)) {
|
|
|
|
bool considerVisibility =
|
2013-02-27 10:56:45 +08:00
|
|
|
(!LV.isVisibilityExplicit() &&
|
|
|
|
!classLV.isVisibilityExplicit() &&
|
2013-02-20 09:54:26 +08:00
|
|
|
!hasExplicitVisibilityAlready(computation));
|
2013-02-16 08:17:33 +08:00
|
|
|
LinkageInfo tempLV =
|
2013-05-29 12:55:30 +08:00
|
|
|
getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
|
2013-02-16 08:17:33 +08:00
|
|
|
LV.mergeMaybeWithVisibility(tempLV, considerVisibility);
|
2013-02-22 07:42:58 +08:00
|
|
|
|
|
|
|
if (const RedeclarableTemplateDecl *redeclTemp =
|
|
|
|
dyn_cast<RedeclarableTemplateDecl>(temp)) {
|
|
|
|
if (isExplicitMemberSpecialization(redeclTemp)) {
|
|
|
|
explicitSpecSuppressor = temp->getTemplatedDecl();
|
|
|
|
}
|
|
|
|
}
|
2010-10-30 06:22:43 +08:00
|
|
|
}
|
|
|
|
|
2013-02-22 07:42:58 +08:00
|
|
|
// We should never be looking for an attribute directly on a template.
|
|
|
|
assert(!explicitSpecSuppressor || !isa<TemplateDecl>(explicitSpecSuppressor));
|
|
|
|
|
|
|
|
// If this member is an explicit member specialization, and it has
|
|
|
|
// an explicit attribute, ignore visibility from the parent.
|
|
|
|
bool considerClassVisibility = true;
|
|
|
|
if (explicitSpecSuppressor &&
|
2013-02-27 10:56:45 +08:00
|
|
|
// optimization: hasDVA() is true only with explicit visibility.
|
|
|
|
LV.isVisibilityExplicit() &&
|
|
|
|
classLV.getVisibility() != DefaultVisibility &&
|
2013-02-22 07:42:58 +08:00
|
|
|
hasDirectVisibilityAttribute(explicitSpecSuppressor, computation)) {
|
|
|
|
considerClassVisibility = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Finally, merge in information from the class.
|
|
|
|
LV.mergeMaybeWithVisibility(classLV, considerClassVisibility);
|
2010-10-23 05:05:15 +08:00
|
|
|
return LV;
|
2010-08-13 16:35:10 +08:00
|
|
|
}
|
|
|
|
|
2011-12-20 10:48:34 +08:00
|
|
|
void NamedDecl::anchor() { }
|
|
|
|
|
2013-05-29 12:55:30 +08:00
|
|
|
static LinkageInfo computeLVForDecl(const NamedDecl *D,
|
|
|
|
LVComputationKind computation);
|
|
|
|
|
2013-03-14 11:07:35 +08:00
|
|
|
bool NamedDecl::isLinkageValid() const {
|
2013-05-26 01:16:20 +08:00
|
|
|
if (!hasCachedLinkage())
|
2013-03-14 11:07:35 +08:00
|
|
|
return true;
|
2011-02-19 10:53:41 +08:00
|
|
|
|
2013-05-29 12:55:30 +08:00
|
|
|
return computeLVForDecl(this, LVForLinkageOnly).getLinkage() ==
|
2013-05-26 01:16:20 +08:00
|
|
|
getCachedLinkage();
|
2011-02-09 03:01:05 +08:00
|
|
|
}
|
|
|
|
|
2014-09-10 07:10:54 +08:00
|
|
|
ObjCStringFormatFamily NamedDecl::getObjCFStringFormattingFamily() const {
|
|
|
|
StringRef name = getName();
|
|
|
|
if (name.empty()) return SFF_None;
|
|
|
|
|
|
|
|
if (name.front() == 'C')
|
|
|
|
if (name == "CFStringCreateWithFormat" ||
|
|
|
|
name == "CFStringCreateWithFormatAndArguments" ||
|
|
|
|
name == "CFStringAppendFormat" ||
|
|
|
|
name == "CFStringAppendFormatAndArguments")
|
|
|
|
return SFF_CFString;
|
|
|
|
return SFF_None;
|
|
|
|
}
|
|
|
|
|
2013-05-13 08:12:11 +08:00
|
|
|
Linkage NamedDecl::getLinkageInternal() const {
|
2013-02-20 09:54:26 +08:00
|
|
|
// We don't care about visibility here, so ask for the cheapest
|
|
|
|
// possible visibility analysis.
|
2013-05-29 03:43:11 +08:00
|
|
|
return getLVForDecl(this, LVForLinkageOnly).getLinkage();
|
2010-12-07 02:36:25 +08:00
|
|
|
}
|
|
|
|
|
2010-10-30 19:50:40 +08:00
|
|
|
LinkageInfo NamedDecl::getLinkageAndVisibility() const {
|
2013-02-16 08:17:33 +08:00
|
|
|
LVComputationKind computation =
|
|
|
|
(usesTypeVisibility(this) ? LVForType : LVForValue);
|
2013-05-29 03:43:11 +08:00
|
|
|
return getLVForDecl(this, computation);
|
2010-10-29 08:29:13 +08:00
|
|
|
}
|
2010-04-21 07:15:35 +08:00
|
|
|
|
2013-11-27 00:09:08 +08:00
|
|
|
static Optional<Visibility>
|
|
|
|
getExplicitVisibilityAux(const NamedDecl *ND,
|
|
|
|
NamedDecl::ExplicitVisibilityKind kind,
|
|
|
|
bool IsMostRecent) {
|
|
|
|
assert(!IsMostRecent || ND == ND->getMostRecentDecl());
|
|
|
|
|
2013-02-27 03:33:14 +08:00
|
|
|
// Check the declaration itself first.
|
2013-11-27 00:09:08 +08:00
|
|
|
if (Optional<Visibility> V = getVisibilityOf(ND, kind))
|
2013-02-27 03:33:14 +08:00
|
|
|
return V;
|
|
|
|
|
|
|
|
// If this is a member class of a specialization of a class template
|
|
|
|
// and the corresponding decl has explicit visibility, use that.
|
2013-11-27 00:09:08 +08:00
|
|
|
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(ND)) {
|
2013-02-27 03:33:14 +08:00
|
|
|
CXXRecordDecl *InstantiatedFrom = RD->getInstantiatedFromMemberClass();
|
|
|
|
if (InstantiatedFrom)
|
|
|
|
return getVisibilityOf(InstantiatedFrom, kind);
|
|
|
|
}
|
2012-05-16 10:10:38 +08:00
|
|
|
|
2013-02-27 03:33:14 +08:00
|
|
|
// If there wasn't explicit visibility there, and this is a
|
|
|
|
// specialization of a class template, check for visibility
|
|
|
|
// on the pattern.
|
|
|
|
if (const ClassTemplateSpecializationDecl *spec
|
2013-11-27 00:09:08 +08:00
|
|
|
= dyn_cast<ClassTemplateSpecializationDecl>(ND))
|
2013-02-27 03:33:14 +08:00
|
|
|
return getVisibilityOf(spec->getSpecializedTemplate()->getTemplatedDecl(),
|
|
|
|
kind);
|
|
|
|
|
|
|
|
// Use the most recent declaration.
|
2013-12-08 09:13:22 +08:00
|
|
|
if (!IsMostRecent && !isa<NamespaceDecl>(ND)) {
|
2013-11-27 00:09:08 +08:00
|
|
|
const NamedDecl *MostRecent = ND->getMostRecentDecl();
|
|
|
|
if (MostRecent != ND)
|
|
|
|
return getExplicitVisibilityAux(MostRecent, kind, true);
|
|
|
|
}
|
2013-02-27 03:33:14 +08:00
|
|
|
|
2013-11-27 00:09:08 +08:00
|
|
|
if (const VarDecl *Var = dyn_cast<VarDecl>(ND)) {
|
2012-05-16 10:10:38 +08:00
|
|
|
if (Var->isStaticDataMember()) {
|
|
|
|
VarDecl *InstantiatedFrom = Var->getInstantiatedFromStaticDataMember();
|
|
|
|
if (InstantiatedFrom)
|
2013-02-20 09:54:26 +08:00
|
|
|
return getVisibilityOf(InstantiatedFrom, kind);
|
2012-05-16 10:10:38 +08:00
|
|
|
}
|
2011-03-26 20:10:19 +08:00
|
|
|
|
2014-04-29 15:32:26 +08:00
|
|
|
if (const auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(Var))
|
|
|
|
return getVisibilityOf(VTSD->getSpecializedTemplate()->getTemplatedDecl(),
|
|
|
|
kind);
|
|
|
|
|
2013-02-21 09:47:18 +08:00
|
|
|
return None;
|
2012-05-16 10:10:38 +08:00
|
|
|
}
|
2013-02-27 03:33:14 +08:00
|
|
|
// Also handle function template specializations.
|
2013-11-27 00:09:08 +08:00
|
|
|
if (const FunctionDecl *fn = dyn_cast<FunctionDecl>(ND)) {
|
2011-03-26 20:10:19 +08:00
|
|
|
// If the function is a specialization of a template with an
|
|
|
|
// explicit visibility attribute, use that.
|
|
|
|
if (FunctionTemplateSpecializationInfo *templateInfo
|
|
|
|
= fn->getTemplateSpecializationInfo())
|
2013-02-20 09:54:26 +08:00
|
|
|
return getVisibilityOf(templateInfo->getTemplate()->getTemplatedDecl(),
|
|
|
|
kind);
|
2011-03-26 20:10:19 +08:00
|
|
|
|
2012-02-23 12:17:32 +08:00
|
|
|
// If the function is a member of a specialization of a class template
|
|
|
|
// and the corresponding decl has explicit visibility, use that.
|
|
|
|
FunctionDecl *InstantiatedFrom = fn->getInstantiatedFromMemberFunction();
|
|
|
|
if (InstantiatedFrom)
|
2013-02-20 09:54:26 +08:00
|
|
|
return getVisibilityOf(InstantiatedFrom, kind);
|
2012-02-23 12:17:32 +08:00
|
|
|
|
2013-02-21 09:47:18 +08:00
|
|
|
return None;
|
2011-03-26 20:10:19 +08:00
|
|
|
}
|
|
|
|
|
2012-08-01 03:02:02 +08:00
|
|
|
// The visibility of a template is stored in the templated decl.
|
2013-11-27 00:09:08 +08:00
|
|
|
if (const TemplateDecl *TD = dyn_cast<TemplateDecl>(ND))
|
2013-02-20 09:54:26 +08:00
|
|
|
return getVisibilityOf(TD->getTemplatedDecl(), kind);
|
2012-08-01 03:02:02 +08:00
|
|
|
|
2013-02-21 09:47:18 +08:00
|
|
|
return None;
|
2011-03-26 20:10:19 +08:00
|
|
|
}
|
|
|
|
|
2013-11-27 00:09:08 +08:00
|
|
|
Optional<Visibility>
|
|
|
|
NamedDecl::getExplicitVisibility(ExplicitVisibilityKind kind) const {
|
|
|
|
return getExplicitVisibilityAux(this, kind, false);
|
|
|
|
}
|
|
|
|
|
2013-07-02 04:22:57 +08:00
|
|
|
static LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
|
|
|
|
LVComputationKind computation) {
|
|
|
|
// This lambda has its linkage/visibility determined by its owner.
|
|
|
|
if (ContextDecl) {
|
|
|
|
if (isa<ParmVarDecl>(ContextDecl))
|
|
|
|
DC = ContextDecl->getDeclContext()->getRedeclContext();
|
|
|
|
else
|
|
|
|
return getLVForDecl(cast<NamedDecl>(ContextDecl), computation);
|
|
|
|
}
|
2013-09-30 04:27:06 +08:00
|
|
|
|
2013-07-02 04:22:57 +08:00
|
|
|
if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC))
|
|
|
|
return getLVForDecl(ND, computation);
|
2013-09-30 04:27:06 +08:00
|
|
|
|
2013-07-02 04:22:57 +08:00
|
|
|
return LinkageInfo::external();
|
|
|
|
}
|
|
|
|
|
2013-02-16 08:17:33 +08:00
|
|
|
static LinkageInfo getLVForLocalDecl(const NamedDecl *D,
|
|
|
|
LVComputationKind computation) {
|
|
|
|
if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
|
|
|
|
if (Function->isInAnonymousNamespace() &&
|
2013-05-06 04:15:21 +08:00
|
|
|
!Function->isInExternCContext())
|
2013-02-16 08:17:33 +08:00
|
|
|
return LinkageInfo::uniqueExternal();
|
|
|
|
|
|
|
|
// This is a "void f();" which got merged with a file static.
|
2013-04-04 03:27:57 +08:00
|
|
|
if (Function->getCanonicalDecl()->getStorageClass() == SC_Static)
|
2013-02-16 08:17:33 +08:00
|
|
|
return LinkageInfo::internal();
|
|
|
|
|
|
|
|
LinkageInfo LV;
|
2013-02-20 09:54:26 +08:00
|
|
|
if (!hasExplicitVisibilityAlready(computation)) {
|
2013-02-21 06:23:23 +08:00
|
|
|
if (Optional<Visibility> Vis =
|
|
|
|
getExplicitVisibility(Function, computation))
|
2013-02-16 08:17:33 +08:00
|
|
|
LV.mergeVisibility(*Vis, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Note that Sema::MergeCompatibleFunctionDecls already takes care of
|
|
|
|
// merging storage classes and visibility attributes, so we don't have to
|
|
|
|
// look at previous decls in here.
|
|
|
|
|
|
|
|
return LV;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
|
2013-04-04 03:27:57 +08:00
|
|
|
if (Var->hasExternalStorage()) {
|
2013-05-06 04:15:21 +08:00
|
|
|
if (Var->isInAnonymousNamespace() && !Var->isInExternCContext())
|
2013-02-16 08:17:33 +08:00
|
|
|
return LinkageInfo::uniqueExternal();
|
|
|
|
|
|
|
|
LinkageInfo LV;
|
|
|
|
if (Var->getStorageClass() == SC_PrivateExtern)
|
|
|
|
LV.mergeVisibility(HiddenVisibility, true);
|
2013-02-20 09:54:26 +08:00
|
|
|
else if (!hasExplicitVisibilityAlready(computation)) {
|
2013-02-21 06:23:23 +08:00
|
|
|
if (Optional<Visibility> Vis = getExplicitVisibility(Var, computation))
|
2013-02-16 08:17:33 +08:00
|
|
|
LV.mergeVisibility(*Vis, true);
|
|
|
|
}
|
|
|
|
|
2013-04-04 03:27:57 +08:00
|
|
|
if (const VarDecl *Prev = Var->getPreviousDecl()) {
|
|
|
|
LinkageInfo PrevLV = getLVForDecl(Prev, computation);
|
|
|
|
if (PrevLV.getLinkage())
|
|
|
|
LV.setLinkage(PrevLV.getLinkage());
|
|
|
|
LV.mergeVisibility(PrevLV);
|
|
|
|
}
|
|
|
|
|
2013-02-16 08:17:33 +08:00
|
|
|
return LV;
|
|
|
|
}
|
2013-06-18 04:04:51 +08:00
|
|
|
|
|
|
|
if (!Var->isStaticLocal())
|
|
|
|
return LinkageInfo::none();
|
2013-02-16 08:17:33 +08:00
|
|
|
}
|
|
|
|
|
2013-06-18 04:04:51 +08:00
|
|
|
ASTContext &Context = D->getASTContext();
|
|
|
|
if (!Context.getLangOpts().CPlusPlus)
|
2013-05-26 01:16:20 +08:00
|
|
|
return LinkageInfo::none();
|
|
|
|
|
2013-07-02 04:22:57 +08:00
|
|
|
const Decl *OuterD = getOutermostFuncOrBlockContext(D);
|
|
|
|
if (!OuterD)
|
2013-06-04 21:43:35 +08:00
|
|
|
return LinkageInfo::none();
|
|
|
|
|
2013-07-02 04:22:57 +08:00
|
|
|
LinkageInfo LV;
|
|
|
|
if (const BlockDecl *BD = dyn_cast<BlockDecl>(OuterD)) {
|
|
|
|
if (!BD->getBlockManglingNumber())
|
|
|
|
return LinkageInfo::none();
|
|
|
|
|
|
|
|
LV = getLVForClosure(BD->getDeclContext()->getRedeclContext(),
|
|
|
|
BD->getBlockManglingContextDecl(), computation);
|
|
|
|
} else {
|
|
|
|
const FunctionDecl *FD = cast<FunctionDecl>(OuterD);
|
|
|
|
if (!FD->isInlined() &&
|
2014-12-16 12:52:14 +08:00
|
|
|
!isTemplateInstantiation(FD->getTemplateSpecializationKind()))
|
2013-07-02 04:22:57 +08:00
|
|
|
return LinkageInfo::none();
|
2013-06-04 21:43:35 +08:00
|
|
|
|
2013-07-02 04:22:57 +08:00
|
|
|
LV = getLVForDecl(FD, computation);
|
|
|
|
}
|
2013-05-27 22:50:21 +08:00
|
|
|
if (!isExternallyVisible(LV.getLinkage()))
|
2013-05-26 01:16:20 +08:00
|
|
|
return LinkageInfo::none();
|
|
|
|
return LinkageInfo(VisibleNoLinkage, LV.getVisibility(),
|
|
|
|
LV.isVisibilityExplicit());
|
2013-02-16 08:17:33 +08:00
|
|
|
}
|
|
|
|
|
2013-10-01 10:51:53 +08:00
|
|
|
static inline const CXXRecordDecl*
|
|
|
|
getOutermostEnclosingLambda(const CXXRecordDecl *Record) {
|
|
|
|
const CXXRecordDecl *Ret = Record;
|
|
|
|
while (Record && Record->isLambda()) {
|
|
|
|
Ret = Record;
|
|
|
|
if (!Record->getParent()) break;
|
|
|
|
// Get the Containing Class of this Lambda Class
|
|
|
|
Record = dyn_cast_or_null<CXXRecordDecl>(
|
|
|
|
Record->getParent()->getParent());
|
|
|
|
}
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
2013-05-29 03:43:11 +08:00
|
|
|
static LinkageInfo computeLVForDecl(const NamedDecl *D,
|
|
|
|
LVComputationKind computation) {
|
2010-04-21 07:15:35 +08:00
|
|
|
// Objective-C: treat all Objective-C declarations as having external
|
|
|
|
// linkage.
|
2010-10-29 08:29:13 +08:00
|
|
|
switch (D->getKind()) {
|
2010-04-21 07:15:35 +08:00
|
|
|
default:
|
|
|
|
break;
|
2011-12-01 09:28:21 +08:00
|
|
|
case Decl::ParmVar:
|
|
|
|
return LinkageInfo::none();
|
2010-10-23 05:05:15 +08:00
|
|
|
case Decl::TemplateTemplateParm: // count these as external
|
|
|
|
case Decl::NonTypeTemplateParm:
|
2010-04-21 07:15:35 +08:00
|
|
|
case Decl::ObjCAtDefsField:
|
|
|
|
case Decl::ObjCCategory:
|
|
|
|
case Decl::ObjCCategoryImpl:
|
|
|
|
case Decl::ObjCCompatibleAlias:
|
|
|
|
case Decl::ObjCImplementation:
|
|
|
|
case Decl::ObjCMethod:
|
|
|
|
case Decl::ObjCProperty:
|
|
|
|
case Decl::ObjCPropertyImpl:
|
|
|
|
case Decl::ObjCProtocol:
|
2010-10-30 19:50:40 +08:00
|
|
|
return LinkageInfo::external();
|
2012-02-21 12:17:39 +08:00
|
|
|
|
|
|
|
case Decl::CXXRecord: {
|
|
|
|
const CXXRecordDecl *Record = cast<CXXRecordDecl>(D);
|
|
|
|
if (Record->isLambda()) {
|
|
|
|
if (!Record->getLambdaManglingNumber()) {
|
|
|
|
// This lambda has no mangling number, so it's internal.
|
|
|
|
return LinkageInfo::internal();
|
|
|
|
}
|
|
|
|
|
2013-10-01 10:51:53 +08:00
|
|
|
// This lambda has its linkage/visibility determined:
|
|
|
|
// - either by the outermost lambda if that lambda has no mangling
|
|
|
|
// number.
|
|
|
|
// - or by the parent of the outer most lambda
|
|
|
|
// This prevents infinite recursion in settings such as nested lambdas
|
|
|
|
// used in NSDMI's, for e.g.
|
|
|
|
// struct L {
|
|
|
|
// int t{};
|
|
|
|
// int t2 = ([](int a) { return [](int b) { return b; };})(t)(t);
|
|
|
|
// };
|
|
|
|
const CXXRecordDecl *OuterMostLambda =
|
|
|
|
getOutermostEnclosingLambda(Record);
|
|
|
|
if (!OuterMostLambda->getLambdaManglingNumber())
|
|
|
|
return LinkageInfo::internal();
|
|
|
|
|
|
|
|
return getLVForClosure(
|
|
|
|
OuterMostLambda->getDeclContext()->getRedeclContext(),
|
|
|
|
OuterMostLambda->getLambdaContextDecl(), computation);
|
2012-02-21 12:17:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2010-04-21 07:15:35 +08:00
|
|
|
}
|
|
|
|
|
2009-11-26 06:24:25 +08:00
|
|
|
// Handle linkage for namespace-scope names.
|
2010-10-29 08:29:13 +08:00
|
|
|
if (D->getDeclContext()->getRedeclContext()->isFileContext())
|
2013-02-16 08:17:33 +08:00
|
|
|
return getLVForNamespaceScopeDecl(D, computation);
|
2009-11-26 06:24:25 +08:00
|
|
|
|
|
|
|
// C++ [basic.link]p5:
|
|
|
|
// In addition, a member function, static data member, a named
|
|
|
|
// class or enumeration of class scope, or an unnamed class or
|
|
|
|
// enumeration defined in a class-scope typedef declaration such
|
|
|
|
// that the class or enumeration has the typedef name for linkage
|
|
|
|
// purposes (7.1.3), has external linkage if the name of the class
|
|
|
|
// has external linkage.
|
2010-10-29 08:29:13 +08:00
|
|
|
if (D->getDeclContext()->isRecord())
|
2013-02-16 08:17:33 +08:00
|
|
|
return getLVForClassMember(D, computation);
|
2009-11-26 06:24:25 +08:00
|
|
|
|
|
|
|
// C++ [basic.link]p6:
|
|
|
|
// The name of a function declared in block scope and the name of
|
|
|
|
// an object declared by a block scope extern declaration have
|
|
|
|
// linkage. If there is a visible declaration of an entity with
|
|
|
|
// linkage having the same name and type, ignoring entities
|
|
|
|
// declared outside the innermost enclosing namespace scope, the
|
|
|
|
// block scope declaration declares that same entity and receives
|
|
|
|
// the linkage of the previous declaration. If there is more than
|
|
|
|
// one such matching entity, the program is ill-formed. Otherwise,
|
|
|
|
// if no matching entity is found, the block scope entity receives
|
|
|
|
// external linkage.
|
2013-02-16 08:17:33 +08:00
|
|
|
if (D->getDeclContext()->isFunctionOrMethod())
|
|
|
|
return getLVForLocalDecl(D, computation);
|
2009-11-26 06:24:25 +08:00
|
|
|
|
|
|
|
// C++ [basic.link]p6:
|
|
|
|
// Names not covered by these rules have no linkage.
|
2010-10-30 19:50:40 +08:00
|
|
|
return LinkageInfo::none();
|
2010-10-23 05:05:15 +08:00
|
|
|
}
|
2009-11-26 06:24:25 +08:00
|
|
|
|
2013-05-29 03:43:11 +08:00
|
|
|
namespace clang {
|
|
|
|
class LinkageComputer {
|
|
|
|
public:
|
|
|
|
static LinkageInfo getLVForDecl(const NamedDecl *D,
|
|
|
|
LVComputationKind computation) {
|
|
|
|
if (computation == LVForLinkageOnly && D->hasCachedLinkage())
|
|
|
|
return LinkageInfo(D->getCachedLinkage(), DefaultVisibility, false);
|
|
|
|
|
|
|
|
LinkageInfo LV = computeLVForDecl(D, computation);
|
|
|
|
if (D->hasCachedLinkage())
|
|
|
|
assert(D->getCachedLinkage() == LV.getLinkage());
|
|
|
|
|
|
|
|
D->setCachedLinkage(LV.getLinkage());
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
// In C (because of gnu inline) and in c++ with microsoft extensions an
|
|
|
|
// static can follow an extern, so we can have two decls with different
|
|
|
|
// linkages.
|
|
|
|
const LangOptions &Opts = D->getASTContext().getLangOpts();
|
|
|
|
if (!Opts.CPlusPlus || Opts.MicrosoftExt)
|
|
|
|
return LV;
|
|
|
|
|
|
|
|
// We have just computed the linkage for this decl. By induction we know
|
|
|
|
// that all other computed linkages match, check that the one we just
|
2014-03-07 05:48:45 +08:00
|
|
|
// computed also does.
|
2014-05-12 13:36:57 +08:00
|
|
|
NamedDecl *Old = nullptr;
|
2014-03-07 07:45:36 +08:00
|
|
|
for (auto I : D->redecls()) {
|
|
|
|
NamedDecl *T = cast<NamedDecl>(I);
|
2013-05-29 03:43:11 +08:00
|
|
|
if (T == D)
|
|
|
|
continue;
|
2014-03-07 05:48:45 +08:00
|
|
|
if (!T->isInvalidDecl() && T->hasCachedLinkage()) {
|
2013-05-29 03:43:11 +08:00
|
|
|
Old = T;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert(!Old || Old->getCachedLinkage() == D->getCachedLinkage());
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return LV;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
static LinkageInfo getLVForDecl(const NamedDecl *D,
|
|
|
|
LVComputationKind computation) {
|
|
|
|
return clang::LinkageComputer::getLVForDecl(D, computation);
|
|
|
|
}
|
|
|
|
|
2009-02-05 01:27:36 +08:00
|
|
|
std::string NamedDecl::getQualifiedNameAsString() const {
|
2013-02-23 21:53:57 +08:00
|
|
|
std::string QualName;
|
|
|
|
llvm::raw_string_ostream OS(QualName);
|
2014-01-04 02:42:48 +08:00
|
|
|
printQualifiedName(OS, getASTContext().getPrintingPolicy());
|
2013-02-23 21:53:57 +08:00
|
|
|
return OS.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
void NamedDecl::printQualifiedName(raw_ostream &OS) const {
|
|
|
|
printQualifiedName(OS, getASTContext().getPrintingPolicy());
|
|
|
|
}
|
|
|
|
|
|
|
|
void NamedDecl::printQualifiedName(raw_ostream &OS,
|
|
|
|
const PrintingPolicy &P) const {
|
2009-02-05 01:27:36 +08:00
|
|
|
const DeclContext *Ctx = getDeclContext();
|
|
|
|
|
2013-02-23 21:53:57 +08:00
|
|
|
if (Ctx->isFunctionOrMethod()) {
|
|
|
|
printName(OS);
|
|
|
|
return;
|
|
|
|
}
|
2009-02-05 01:27:36 +08:00
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
typedef SmallVector<const DeclContext *, 8> ContextsTy;
|
2010-04-28 22:33:51 +08:00
|
|
|
ContextsTy Contexts;
|
|
|
|
|
|
|
|
// Collect contexts.
|
|
|
|
while (Ctx && isa<NamedDecl>(Ctx)) {
|
|
|
|
Contexts.push_back(Ctx);
|
|
|
|
Ctx = Ctx->getParent();
|
2013-02-23 21:53:57 +08:00
|
|
|
}
|
2010-04-28 22:33:51 +08:00
|
|
|
|
|
|
|
for (ContextsTy::reverse_iterator I = Contexts.rbegin(), E = Contexts.rend();
|
|
|
|
I != E; ++I) {
|
2009-09-09 23:08:12 +08:00
|
|
|
if (const ClassTemplateSpecializationDecl *Spec
|
2010-04-28 22:33:51 +08:00
|
|
|
= dyn_cast<ClassTemplateSpecializationDecl>(*I)) {
|
2013-02-22 23:46:01 +08:00
|
|
|
OS << Spec->getName();
|
2009-05-19 01:01:57 +08:00
|
|
|
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
|
2013-02-22 23:46:01 +08:00
|
|
|
TemplateSpecializationType::PrintTemplateArgumentList(OS,
|
|
|
|
TemplateArgs.data(),
|
|
|
|
TemplateArgs.size(),
|
|
|
|
P);
|
2010-04-28 22:33:51 +08:00
|
|
|
} else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(*I)) {
|
2014-05-31 06:16:51 +08:00
|
|
|
if (P.SuppressUnwrittenScope &&
|
|
|
|
(ND->isAnonymousNamespace() || ND->isInline()))
|
|
|
|
continue;
|
2009-12-25 07:15:03 +08:00
|
|
|
if (ND->isAnonymousNamespace())
|
2014-04-02 13:58:29 +08:00
|
|
|
OS << "(anonymous namespace)";
|
2009-12-25 07:15:03 +08:00
|
|
|
else
|
2011-10-15 02:45:37 +08:00
|
|
|
OS << *ND;
|
2010-04-28 22:33:51 +08:00
|
|
|
} else if (const RecordDecl *RD = dyn_cast<RecordDecl>(*I)) {
|
|
|
|
if (!RD->getIdentifier())
|
2014-04-02 13:58:29 +08:00
|
|
|
OS << "(anonymous " << RD->getKindName() << ')';
|
2010-04-28 22:33:51 +08:00
|
|
|
else
|
2011-10-15 02:45:37 +08:00
|
|
|
OS << *RD;
|
2010-04-28 22:33:51 +08:00
|
|
|
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
|
2014-05-12 13:36:57 +08:00
|
|
|
const FunctionProtoType *FT = nullptr;
|
2009-12-28 11:19:38 +08:00
|
|
|
if (FD->hasWrittenPrototype())
|
2012-08-31 06:22:09 +08:00
|
|
|
FT = dyn_cast<FunctionProtoType>(FD->getType()->castAs<FunctionType>());
|
2009-12-28 11:19:38 +08:00
|
|
|
|
2011-10-15 02:45:37 +08:00
|
|
|
OS << *FD << '(';
|
2009-12-28 11:19:38 +08:00
|
|
|
if (FT) {
|
|
|
|
unsigned NumParams = FD->getNumParams();
|
|
|
|
for (unsigned i = 0; i < NumParams; ++i) {
|
|
|
|
if (i)
|
2010-04-28 22:33:51 +08:00
|
|
|
OS << ", ";
|
2012-05-05 12:20:37 +08:00
|
|
|
OS << FD->getParamDecl(i)->getType().stream(P);
|
2009-12-28 11:19:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (FT->isVariadic()) {
|
|
|
|
if (NumParams > 0)
|
2010-04-28 22:33:51 +08:00
|
|
|
OS << ", ";
|
|
|
|
OS << "...";
|
2009-12-28 11:19:38 +08:00
|
|
|
}
|
|
|
|
}
|
2010-04-28 22:33:51 +08:00
|
|
|
OS << ')';
|
|
|
|
} else {
|
2011-10-15 02:45:37 +08:00
|
|
|
OS << *cast<NamedDecl>(*I);
|
2010-04-28 22:33:51 +08:00
|
|
|
}
|
|
|
|
OS << "::";
|
2009-02-05 01:27:36 +08:00
|
|
|
}
|
|
|
|
|
2010-03-17 05:48:18 +08:00
|
|
|
if (getDeclName())
|
2011-10-15 02:45:37 +08:00
|
|
|
OS << *this;
|
2010-03-17 05:48:18 +08:00
|
|
|
else
|
2014-04-02 13:58:29 +08:00
|
|
|
OS << "(anonymous)";
|
2013-02-23 21:53:57 +08:00
|
|
|
}
|
2009-02-05 01:27:36 +08:00
|
|
|
|
2013-02-23 21:53:57 +08:00
|
|
|
void NamedDecl::getNameForDiagnostic(raw_ostream &OS,
|
|
|
|
const PrintingPolicy &Policy,
|
|
|
|
bool Qualified) const {
|
|
|
|
if (Qualified)
|
|
|
|
printQualifiedName(OS, Policy);
|
|
|
|
else
|
|
|
|
printName(OS);
|
2009-02-05 01:27:36 +08:00
|
|
|
}
|
|
|
|
|
2015-02-10 11:28:10 +08:00
|
|
|
static bool isKindReplaceableBy(Decl::Kind OldK, Decl::Kind NewK) {
|
|
|
|
// For method declarations, we never replace.
|
|
|
|
if (ObjCMethodDecl::classofKind(NewK))
|
|
|
|
return false;
|
2008-12-24 05:05:05 +08:00
|
|
|
|
2015-02-10 11:28:10 +08:00
|
|
|
if (OldK == NewK)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// A compatibility alias for a class can be replaced by an interface.
|
|
|
|
if (ObjCCompatibleAliasDecl::classofKind(OldK) &&
|
|
|
|
ObjCInterfaceDecl::classofKind(NewK))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// A typedef-declaration, alias-declaration, or Objective-C class declaration
|
|
|
|
// can replace another declaration of the same type. Semantic analysis checks
|
|
|
|
// that we have matching types.
|
|
|
|
if ((TypedefNameDecl::classofKind(OldK) ||
|
|
|
|
ObjCInterfaceDecl::classofKind(OldK)) &&
|
|
|
|
(TypedefNameDecl::classofKind(NewK) ||
|
|
|
|
ObjCInterfaceDecl::classofKind(NewK)))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Otherwise, a kind mismatch implies that the declaration is not replaced.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> static bool isRedeclarableImpl(Redeclarable<T> *) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
static bool isRedeclarableImpl(...) { return false; }
|
|
|
|
static bool isRedeclarable(Decl::Kind K) {
|
|
|
|
switch (K) {
|
|
|
|
#define DECL(Type, Base) \
|
|
|
|
case Decl::Type: \
|
|
|
|
return isRedeclarableImpl((Type##Decl *)nullptr);
|
|
|
|
#define ABSTRACT_DECL(DECL)
|
|
|
|
#include "clang/AST/DeclNodes.inc"
|
2009-02-04 03:21:40 +08:00
|
|
|
}
|
2015-02-10 11:28:10 +08:00
|
|
|
llvm_unreachable("unknown decl kind");
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2015-02-10 11:28:10 +08:00
|
|
|
bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const {
|
|
|
|
assert(getDeclName() == OldD->getDeclName() && "Declaration name mismatch");
|
2008-12-24 05:05:05 +08:00
|
|
|
|
2015-03-06 07:24:12 +08:00
|
|
|
// Never replace one imported declaration with another; we need both results
|
|
|
|
// when re-exporting.
|
|
|
|
if (OldD->isFromASTFile() && isFromASTFile())
|
|
|
|
return false;
|
|
|
|
|
2015-02-10 11:28:10 +08:00
|
|
|
if (!isKindReplaceableBy(OldD->getKind(), getKind()))
|
2009-02-23 03:35:57 +08:00
|
|
|
return false;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2015-02-10 11:28:10 +08:00
|
|
|
// Inline namespaces can give us two declarations with the same
|
|
|
|
// name and kind in the same scope but different contexts; we should
|
|
|
|
// keep both declarations in this case.
|
|
|
|
if (!this->getDeclContext()->getRedeclContext()->Equals(
|
|
|
|
OldD->getDeclContext()->getRedeclContext()))
|
|
|
|
return false;
|
2009-10-10 05:13:30 +08:00
|
|
|
|
2015-02-10 11:28:10 +08:00
|
|
|
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this))
|
|
|
|
// For function declarations, we keep track of redeclarations.
|
|
|
|
// FIXME: This returns false for functions that should in fact be replaced.
|
|
|
|
// Instead, perform some kind of type check?
|
|
|
|
if (FD->getPreviousDecl() != OldD)
|
|
|
|
return false;
|
2009-11-17 13:59:44 +08:00
|
|
|
|
2015-02-10 11:28:10 +08:00
|
|
|
// For function templates, the underlying function declarations are linked.
|
|
|
|
if (const FunctionTemplateDecl *FunctionTemplate =
|
|
|
|
dyn_cast<FunctionTemplateDecl>(this))
|
|
|
|
return FunctionTemplate->getTemplatedDecl()->declarationReplaces(
|
|
|
|
cast<FunctionTemplateDecl>(OldD)->getTemplatedDecl());
|
|
|
|
|
|
|
|
// Using shadow declarations can be overloaded on their target declarations
|
|
|
|
// if they introduce functions.
|
|
|
|
// FIXME: If our target replaces the old target, can we replace the old
|
|
|
|
// shadow declaration?
|
|
|
|
if (auto *USD = dyn_cast<UsingShadowDecl>(this))
|
|
|
|
if (USD->getTargetDecl() != cast<UsingShadowDecl>(OldD)->getTargetDecl())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Using declarations can be overloaded if they introduce functions.
|
|
|
|
if (auto *UD = dyn_cast<UsingDecl>(this)) {
|
2011-02-25 08:36:19 +08:00
|
|
|
ASTContext &Context = getASTContext();
|
2015-02-10 11:28:10 +08:00
|
|
|
return Context.getCanonicalNestedNameSpecifier(UD->getQualifier()) ==
|
2011-02-25 08:36:19 +08:00
|
|
|
Context.getCanonicalNestedNameSpecifier(
|
2015-02-10 11:28:10 +08:00
|
|
|
cast<UsingDecl>(OldD)->getQualifier());
|
2013-08-20 08:39:40 +08:00
|
|
|
}
|
2015-02-10 11:28:10 +08:00
|
|
|
if (auto *UUVD = dyn_cast<UnresolvedUsingValueDecl>(this)) {
|
2013-08-20 08:39:40 +08:00
|
|
|
ASTContext &Context = getASTContext();
|
2015-02-10 11:28:10 +08:00
|
|
|
return Context.getCanonicalNestedNameSpecifier(UUVD->getQualifier()) ==
|
2013-08-20 08:39:40 +08:00
|
|
|
Context.getCanonicalNestedNameSpecifier(
|
|
|
|
cast<UnresolvedUsingValueDecl>(OldD)->getQualifier());
|
2011-02-25 08:36:19 +08:00
|
|
|
}
|
2010-11-04 16:48:52 +08:00
|
|
|
|
2015-02-10 11:28:10 +08:00
|
|
|
// UsingDirectiveDecl's are not really NamedDecl's, and all have same name.
|
|
|
|
// We want to keep it, unless it nominates same namespace.
|
|
|
|
if (auto *UD = dyn_cast<UsingDirectiveDecl>(this))
|
|
|
|
return UD->getNominatedNamespace()->getOriginalNamespace() ==
|
|
|
|
cast<UsingDirectiveDecl>(OldD)->getNominatedNamespace()
|
|
|
|
->getOriginalNamespace();
|
|
|
|
|
|
|
|
if (!IsKnownNewer && isRedeclarable(getKind())) {
|
|
|
|
// Check whether this is actually newer than OldD. We want to keep the
|
|
|
|
// newer declaration. This loop will usually only iterate once, because
|
|
|
|
// OldD is usually the previous declaration.
|
|
|
|
for (auto D : redecls()) {
|
|
|
|
if (D == OldD)
|
|
|
|
break;
|
|
|
|
|
|
|
|
// If we reach the canonical declaration, then OldD is not actually older
|
|
|
|
// than this one.
|
|
|
|
//
|
|
|
|
// FIXME: In this case, we should not add this decl to the lookup table.
|
|
|
|
if (D->isCanonicalDecl())
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2014-03-18 05:46:03 +08:00
|
|
|
|
2015-02-10 11:28:10 +08:00
|
|
|
// It's a newer declaration of the same kind of declaration in the same scope,
|
|
|
|
// and not an overload: we want this decl instead of the existing one.
|
|
|
|
return true;
|
2008-12-24 05:05:05 +08:00
|
|
|
}
|
|
|
|
|
2009-02-25 04:03:32 +08:00
|
|
|
bool NamedDecl::hasLinkage() const {
|
2013-05-26 01:16:20 +08:00
|
|
|
return getFormalLinkage() != NoLinkage;
|
2009-02-25 04:03:32 +08:00
|
|
|
}
|
2009-01-20 09:17:11 +08:00
|
|
|
|
2012-03-09 02:20:41 +08:00
|
|
|
NamedDecl *NamedDecl::getUnderlyingDeclImpl() {
|
2009-06-26 14:29:23 +08:00
|
|
|
NamedDecl *ND = this;
|
2012-03-09 05:00:45 +08:00
|
|
|
while (UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(ND))
|
|
|
|
ND = UD->getTargetDecl();
|
|
|
|
|
|
|
|
if (ObjCCompatibleAliasDecl *AD = dyn_cast<ObjCCompatibleAliasDecl>(ND))
|
|
|
|
return AD->getClassInterface();
|
|
|
|
|
|
|
|
return ND;
|
2009-06-26 14:29:23 +08:00
|
|
|
}
|
|
|
|
|
2010-04-07 05:38:20 +08:00
|
|
|
bool NamedDecl::isCXXInstanceMember() const {
|
2012-03-08 10:08:05 +08:00
|
|
|
if (!isCXXClassMember())
|
|
|
|
return false;
|
|
|
|
|
2010-04-07 05:38:20 +08:00
|
|
|
const NamedDecl *D = this;
|
|
|
|
if (isa<UsingShadowDecl>(D))
|
|
|
|
D = cast<UsingShadowDecl>(D)->getTargetDecl();
|
|
|
|
|
2013-04-16 15:28:30 +08:00
|
|
|
if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D) || isa<MSPropertyDecl>(D))
|
2010-04-07 05:38:20 +08:00
|
|
|
return true;
|
2014-01-22 15:29:52 +08:00
|
|
|
if (const CXXMethodDecl *MD =
|
|
|
|
dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()))
|
|
|
|
return MD->isInstance();
|
2010-04-07 05:38:20 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-08-21 08:31:54 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// DeclaratorDecl Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-07-07 02:42:40 +08:00
|
|
|
template <typename DeclT>
|
|
|
|
static SourceLocation getTemplateOrInnerLocStart(const DeclT *decl) {
|
|
|
|
if (decl->getNumTemplateParameterLists() > 0)
|
|
|
|
return decl->getTemplateParameterList(0)->getTemplateLoc();
|
|
|
|
else
|
|
|
|
return decl->getInnerLocStart();
|
|
|
|
}
|
|
|
|
|
2009-08-21 08:31:54 +08:00
|
|
|
SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const {
|
2010-05-29 07:32:21 +08:00
|
|
|
TypeSourceInfo *TSI = getTypeSourceInfo();
|
|
|
|
if (TSI) return TSI->getTypeLoc().getBeginLoc();
|
2009-08-21 08:31:54 +08:00
|
|
|
return SourceLocation();
|
|
|
|
}
|
|
|
|
|
2011-02-25 10:25:35 +08:00
|
|
|
void DeclaratorDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
|
|
|
|
if (QualifierLoc) {
|
2010-03-15 18:12:16 +08:00
|
|
|
// Make sure the extended decl info is allocated.
|
|
|
|
if (!hasExtInfo()) {
|
|
|
|
// Save (non-extended) type source info pointer.
|
|
|
|
TypeSourceInfo *savedTInfo = DeclInfo.get<TypeSourceInfo*>();
|
|
|
|
// Allocate external info struct.
|
|
|
|
DeclInfo = new (getASTContext()) ExtInfo;
|
|
|
|
// Restore savedTInfo into (extended) decl info.
|
|
|
|
getExtInfo()->TInfo = savedTInfo;
|
|
|
|
}
|
|
|
|
// Set qualifier info.
|
2011-02-25 10:25:35 +08:00
|
|
|
getExtInfo()->QualifierLoc = QualifierLoc;
|
2011-08-18 07:08:45 +08:00
|
|
|
} else {
|
2010-03-15 18:12:16 +08:00
|
|
|
// Here Qualifier == 0, i.e., we are removing the qualifier (if any).
|
|
|
|
if (hasExtInfo()) {
|
2011-03-18 23:16:37 +08:00
|
|
|
if (getExtInfo()->NumTemplParamLists == 0) {
|
|
|
|
// Save type source info pointer.
|
|
|
|
TypeSourceInfo *savedTInfo = getExtInfo()->TInfo;
|
|
|
|
// Deallocate the extended decl info.
|
|
|
|
getASTContext().Deallocate(getExtInfo());
|
|
|
|
// Restore savedTInfo into (non-extended) decl info.
|
|
|
|
DeclInfo = savedTInfo;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
getExtInfo()->QualifierLoc = QualifierLoc;
|
2010-03-15 18:12:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-03-18 23:16:37 +08:00
|
|
|
void
|
|
|
|
DeclaratorDecl::setTemplateParameterListsInfo(ASTContext &Context,
|
|
|
|
unsigned NumTPLists,
|
|
|
|
TemplateParameterList **TPLists) {
|
|
|
|
assert(NumTPLists > 0);
|
|
|
|
// Make sure the extended decl info is allocated.
|
|
|
|
if (!hasExtInfo()) {
|
|
|
|
// Save (non-extended) type source info pointer.
|
|
|
|
TypeSourceInfo *savedTInfo = DeclInfo.get<TypeSourceInfo*>();
|
|
|
|
// Allocate external info struct.
|
|
|
|
DeclInfo = new (getASTContext()) ExtInfo;
|
|
|
|
// Restore savedTInfo into (extended) decl info.
|
|
|
|
getExtInfo()->TInfo = savedTInfo;
|
|
|
|
}
|
|
|
|
// Set the template parameter lists info.
|
|
|
|
getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists);
|
|
|
|
}
|
|
|
|
|
2010-07-07 02:42:40 +08:00
|
|
|
SourceLocation DeclaratorDecl::getOuterLocStart() const {
|
|
|
|
return getTemplateOrInnerLocStart(this);
|
|
|
|
}
|
|
|
|
|
2011-03-09 00:41:52 +08:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
// Helper function: returns true if QT is or contains a type
|
|
|
|
// having a postfix component.
|
|
|
|
bool typeIsPostfix(clang::QualType QT) {
|
|
|
|
while (true) {
|
|
|
|
const Type* T = QT.getTypePtr();
|
|
|
|
switch (T->getTypeClass()) {
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
case Type::Pointer:
|
|
|
|
QT = cast<PointerType>(T)->getPointeeType();
|
|
|
|
break;
|
|
|
|
case Type::BlockPointer:
|
|
|
|
QT = cast<BlockPointerType>(T)->getPointeeType();
|
|
|
|
break;
|
|
|
|
case Type::MemberPointer:
|
|
|
|
QT = cast<MemberPointerType>(T)->getPointeeType();
|
|
|
|
break;
|
|
|
|
case Type::LValueReference:
|
|
|
|
case Type::RValueReference:
|
|
|
|
QT = cast<ReferenceType>(T)->getPointeeType();
|
|
|
|
break;
|
|
|
|
case Type::PackExpansion:
|
|
|
|
QT = cast<PackExpansionType>(T)->getPattern();
|
|
|
|
break;
|
|
|
|
case Type::Paren:
|
|
|
|
case Type::ConstantArray:
|
|
|
|
case Type::DependentSizedArray:
|
|
|
|
case Type::IncompleteArray:
|
|
|
|
case Type::VariableArray:
|
|
|
|
case Type::FunctionProto:
|
|
|
|
case Type::FunctionNoProto:
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
SourceRange DeclaratorDecl::getSourceRange() const {
|
|
|
|
SourceLocation RangeEnd = getLocation();
|
|
|
|
if (TypeSourceInfo *TInfo = getTypeSourceInfo()) {
|
2014-02-02 23:28:46 +08:00
|
|
|
// If the declaration has no name or the type extends past the name take the
|
|
|
|
// end location of the type.
|
|
|
|
if (!getDeclName() || typeIsPostfix(TInfo->getType()))
|
2011-03-09 00:41:52 +08:00
|
|
|
RangeEnd = TInfo->getTypeLoc().getSourceRange().getEnd();
|
|
|
|
}
|
|
|
|
return SourceRange(getOuterLocStart(), RangeEnd);
|
|
|
|
}
|
|
|
|
|
2010-06-12 16:15:14 +08:00
|
|
|
void
|
2010-06-16 01:44:38 +08:00
|
|
|
QualifierInfo::setTemplateParameterListsInfo(ASTContext &Context,
|
|
|
|
unsigned NumTPLists,
|
2010-06-12 16:15:14 +08:00
|
|
|
TemplateParameterList **TPLists) {
|
2014-05-12 13:36:57 +08:00
|
|
|
assert((NumTPLists == 0 || TPLists != nullptr) &&
|
2010-06-12 16:15:14 +08:00
|
|
|
"Empty array of template parameters with positive size!");
|
|
|
|
|
|
|
|
// Free previous template parameters (if any).
|
|
|
|
if (NumTemplParamLists > 0) {
|
2010-06-16 01:44:38 +08:00
|
|
|
Context.Deallocate(TemplParamLists);
|
2014-05-12 13:36:57 +08:00
|
|
|
TemplParamLists = nullptr;
|
2010-06-12 16:15:14 +08:00
|
|
|
NumTemplParamLists = 0;
|
|
|
|
}
|
|
|
|
// Set info on matched template parameter lists (if any).
|
|
|
|
if (NumTPLists > 0) {
|
2010-06-16 01:44:38 +08:00
|
|
|
TemplParamLists = new (Context) TemplateParameterList*[NumTPLists];
|
2010-06-12 16:15:14 +08:00
|
|
|
NumTemplParamLists = NumTPLists;
|
2015-04-06 02:55:02 +08:00
|
|
|
std::copy(TPLists, TPLists + NumTPLists, TemplParamLists);
|
2010-06-12 16:15:14 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-18 07:39:55 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// VarDecl Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-01-27 06:01:41 +08:00
|
|
|
const char *VarDecl::getStorageClassSpecifierString(StorageClass SC) {
|
|
|
|
switch (SC) {
|
2011-09-20 05:14:35 +08:00
|
|
|
case SC_None: break;
|
2011-09-20 20:40:26 +08:00
|
|
|
case SC_Auto: return "auto";
|
|
|
|
case SC_Extern: return "extern";
|
|
|
|
case SC_OpenCLWorkGroupLocal: return "<<work-group-local>>";
|
|
|
|
case SC_PrivateExtern: return "__private_extern__";
|
|
|
|
case SC_Register: return "register";
|
|
|
|
case SC_Static: return "static";
|
2010-01-27 06:01:41 +08:00
|
|
|
}
|
|
|
|
|
2011-09-20 20:40:26 +08:00
|
|
|
llvm_unreachable("Invalid storage class");
|
2010-01-27 06:01:41 +08:00
|
|
|
}
|
|
|
|
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
VarDecl::VarDecl(Kind DK, ASTContext &C, DeclContext *DC,
|
|
|
|
SourceLocation StartLoc, SourceLocation IdLoc,
|
|
|
|
IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
|
|
|
|
StorageClass SC)
|
|
|
|
: DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
|
|
|
|
redeclarable_base(C), Init() {
|
2014-03-16 02:54:13 +08:00
|
|
|
static_assert(sizeof(VarDeclBitfields) <= sizeof(unsigned),
|
|
|
|
"VarDeclBitfields too large!");
|
|
|
|
static_assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned),
|
|
|
|
"ParmVarDeclBitfields too large!");
|
2013-08-06 09:03:05 +08:00
|
|
|
AllBits = 0;
|
|
|
|
VarDeclBits.SClass = SC;
|
|
|
|
// Everything else is implicitly initialized to false.
|
|
|
|
}
|
|
|
|
|
2011-03-08 16:55:46 +08:00
|
|
|
VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC,
|
|
|
|
SourceLocation StartL, SourceLocation IdL,
|
2009-12-07 10:54:59 +08:00
|
|
|
IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
|
2013-04-04 03:27:57 +08:00
|
|
|
StorageClass S) {
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
return new (C, DC) VarDecl(Var, C, DC, StartL, IdL, Id, T, TInfo, S);
|
2008-12-18 07:39:55 +08:00
|
|
|
}
|
|
|
|
|
2012-01-06 05:55:30 +08:00
|
|
|
VarDecl *VarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
return new (C, ID)
|
|
|
|
VarDecl(Var, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
|
|
|
|
QualType(), nullptr, SC_None);
|
2012-01-06 05:55:30 +08:00
|
|
|
}
|
|
|
|
|
2010-12-07 02:36:25 +08:00
|
|
|
void VarDecl::setStorageClass(StorageClass SC) {
|
|
|
|
assert(isLegalForVariable(SC));
|
2011-05-01 10:13:58 +08:00
|
|
|
VarDeclBits.SClass = SC;
|
2010-12-07 02:36:25 +08:00
|
|
|
}
|
|
|
|
|
2014-05-01 11:16:47 +08:00
|
|
|
VarDecl::TLSKind VarDecl::getTLSKind() const {
|
|
|
|
switch (VarDeclBits.TSCSpec) {
|
|
|
|
case TSCS_unspecified:
|
|
|
|
if (hasAttr<ThreadAttr>())
|
|
|
|
return TLS_Static;
|
|
|
|
return TLS_None;
|
|
|
|
case TSCS___thread: // Fall through.
|
|
|
|
case TSCS__Thread_local:
|
|
|
|
return TLS_Static;
|
|
|
|
case TSCS_thread_local:
|
|
|
|
return TLS_Dynamic;
|
|
|
|
}
|
|
|
|
llvm_unreachable("Unknown thread storage class specifier!");
|
|
|
|
}
|
|
|
|
|
2010-07-07 02:42:40 +08:00
|
|
|
SourceRange VarDecl::getSourceRange() const {
|
2012-10-09 07:08:41 +08:00
|
|
|
if (const Expr *Init = getInit()) {
|
|
|
|
SourceLocation InitEnd = Init->getLocEnd();
|
2013-01-23 01:00:09 +08:00
|
|
|
// If Init is implicit, ignore its source range and fallback on
|
|
|
|
// DeclaratorDecl::getSourceRange() to handle postfix elements.
|
|
|
|
if (InitEnd.isValid() && InitEnd != getLocation())
|
2012-10-09 07:08:41 +08:00
|
|
|
return SourceRange(getOuterLocStart(), InitEnd);
|
|
|
|
}
|
2011-03-09 00:41:52 +08:00
|
|
|
return DeclaratorDecl::getSourceRange();
|
2009-06-20 16:09:14 +08:00
|
|
|
}
|
|
|
|
|
2013-01-05 05:18:45 +08:00
|
|
|
template<typename T>
|
2014-05-31 14:11:02 +08:00
|
|
|
static LanguageLinkage getDeclLanguageLinkage(const T &D) {
|
2013-02-14 09:47:04 +08:00
|
|
|
// C++ [dcl.link]p1: All function types, function names with external linkage,
|
|
|
|
// and variable names with external linkage have a language linkage.
|
2013-05-13 08:12:11 +08:00
|
|
|
if (!D.hasExternalFormalLinkage())
|
2013-02-14 09:47:04 +08:00
|
|
|
return NoLanguageLinkage;
|
|
|
|
|
|
|
|
// Language linkage is a C++ concept, but saying that everything else in C has
|
2013-01-05 04:41:40 +08:00
|
|
|
// C language linkage fits the implementation nicely.
|
2012-12-28 22:21:58 +08:00
|
|
|
ASTContext &Context = D.getASTContext();
|
|
|
|
if (!Context.getLangOpts().CPlusPlus)
|
2013-02-14 09:18:37 +08:00
|
|
|
return CLanguageLinkage;
|
|
|
|
|
2013-02-14 09:47:04 +08:00
|
|
|
// C++ [dcl.link]p4: A C language linkage is ignored in determining the
|
|
|
|
// language linkage of the names of class members and the function type of
|
|
|
|
// class member functions.
|
2012-12-28 22:21:58 +08:00
|
|
|
const DeclContext *DC = D.getDeclContext();
|
|
|
|
if (DC->isRecord())
|
2013-02-14 09:18:37 +08:00
|
|
|
return CXXLanguageLinkage;
|
2012-12-28 22:21:58 +08:00
|
|
|
|
|
|
|
// If the first decl is in an extern "C" context, any other redeclaration
|
|
|
|
// will have C language linkage. If the first one is not in an extern "C"
|
|
|
|
// context, we would have reported an error for any other decl being in one.
|
2013-05-06 04:15:21 +08:00
|
|
|
if (isFirstInExternCContext(&D))
|
2013-02-14 09:18:37 +08:00
|
|
|
return CLanguageLinkage;
|
|
|
|
return CXXLanguageLinkage;
|
2012-12-28 22:21:58 +08:00
|
|
|
}
|
|
|
|
|
2013-03-14 11:07:35 +08:00
|
|
|
template<typename T>
|
2014-05-31 14:11:02 +08:00
|
|
|
static bool isDeclExternC(const T &D) {
|
2013-03-14 11:07:35 +08:00
|
|
|
// Since the context is ignored for class members, they can only have C++
|
|
|
|
// language linkage or no language linkage.
|
|
|
|
const DeclContext *DC = D.getDeclContext();
|
|
|
|
if (DC->isRecord()) {
|
|
|
|
assert(D.getASTContext().getLangOpts().CPlusPlus);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return D.getLanguageLinkage() == CLanguageLinkage;
|
|
|
|
}
|
|
|
|
|
2013-02-14 09:18:37 +08:00
|
|
|
LanguageLinkage VarDecl::getLanguageLinkage() const {
|
2014-05-31 14:11:02 +08:00
|
|
|
return getDeclLanguageLinkage(*this);
|
2012-12-28 22:21:58 +08:00
|
|
|
}
|
|
|
|
|
2013-03-14 11:07:35 +08:00
|
|
|
bool VarDecl::isExternC() const {
|
2014-05-31 14:11:02 +08:00
|
|
|
return isDeclExternC(*this);
|
2013-03-14 11:07:35 +08:00
|
|
|
}
|
|
|
|
|
2013-05-06 04:15:21 +08:00
|
|
|
bool VarDecl::isInExternCContext() const {
|
2013-11-14 10:13:03 +08:00
|
|
|
return getLexicalDeclContext()->isExternCContext();
|
2013-05-06 04:15:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool VarDecl::isInExternCXXContext() const {
|
2013-11-14 10:13:03 +08:00
|
|
|
return getLexicalDeclContext()->isExternCXXContext();
|
2013-05-06 04:15:21 +08:00
|
|
|
}
|
|
|
|
|
2013-10-17 23:37:26 +08:00
|
|
|
VarDecl *VarDecl::getCanonicalDecl() { return getFirstDecl(); }
|
2010-01-27 06:01:41 +08:00
|
|
|
|
2015-04-16 05:53:00 +08:00
|
|
|
VarDecl::DefinitionKind
|
|
|
|
VarDecl::isThisDeclarationADefinition(ASTContext &C) const {
|
2010-02-01 06:27:38 +08:00
|
|
|
// C++ [basic.def]p2:
|
|
|
|
// A declaration is a definition unless [...] it contains the 'extern'
|
|
|
|
// specifier or a linkage-specification and neither an initializer [...],
|
|
|
|
// it declares a static data member in a class declaration [...].
|
2013-09-28 04:14:12 +08:00
|
|
|
// C++1y [temp.expl.spec]p15:
|
|
|
|
// An explicit specialization of a static data member or an explicit
|
|
|
|
// specialization of a static data member template is a definition if the
|
|
|
|
// declaration includes an initializer; otherwise, it is a declaration.
|
|
|
|
//
|
|
|
|
// FIXME: How do you declare (but not define) a partial specialization of
|
|
|
|
// a static data member template outside the containing class?
|
2010-02-01 06:27:38 +08:00
|
|
|
if (isStaticDataMember()) {
|
2013-09-28 04:14:12 +08:00
|
|
|
if (isOutOfLine() &&
|
|
|
|
(hasInit() ||
|
|
|
|
// If the first declaration is out-of-line, this may be an
|
|
|
|
// instantiation of an out-of-line partial specialization of a variable
|
|
|
|
// template for which we have not yet instantiated the initializer.
|
2013-10-17 23:37:26 +08:00
|
|
|
(getFirstDecl()->isOutOfLine()
|
2013-09-28 04:14:12 +08:00
|
|
|
? getTemplateSpecializationKind() == TSK_Undeclared
|
|
|
|
: getTemplateSpecializationKind() !=
|
|
|
|
TSK_ExplicitSpecialization) ||
|
|
|
|
isa<VarTemplatePartialSpecializationDecl>(this)))
|
2010-02-01 06:27:38 +08:00
|
|
|
return Definition;
|
|
|
|
else
|
|
|
|
return DeclarationOnly;
|
|
|
|
}
|
|
|
|
// C99 6.7p5:
|
|
|
|
// A definition of an identifier is a declaration for that identifier that
|
|
|
|
// [...] causes storage to be reserved for that object.
|
|
|
|
// Note: that applies for all non-file-scope objects.
|
|
|
|
// C99 6.9.2p1:
|
|
|
|
// If the declaration of an identifier for an object has file scope and an
|
|
|
|
// initializer, the declaration is an external definition for the identifier
|
|
|
|
if (hasInit())
|
|
|
|
return Definition;
|
2013-04-25 20:11:36 +08:00
|
|
|
|
2015-04-17 17:50:28 +08:00
|
|
|
if (hasAttr<AliasAttr>() ||
|
|
|
|
(hasAttr<SelectAnyAttr>() && !getAttr<SelectAnyAttr>()->isInherited()))
|
2013-10-23 05:39:03 +08:00
|
|
|
return Definition;
|
|
|
|
|
2013-09-28 04:14:12 +08:00
|
|
|
// A variable template specialization (other than a static data member
|
|
|
|
// template or an explicit specialization) is a declaration until we
|
|
|
|
// instantiate its initializer.
|
|
|
|
if (isa<VarTemplateSpecializationDecl>(this) &&
|
|
|
|
getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
|
|
|
|
return DeclarationOnly;
|
|
|
|
|
2015-04-16 07:04:24 +08:00
|
|
|
if (hasExternalStorage())
|
2010-02-01 06:27:38 +08:00
|
|
|
return DeclarationOnly;
|
2013-03-07 09:42:44 +08:00
|
|
|
|
2013-04-25 20:11:36 +08:00
|
|
|
// [dcl.link] p7:
|
|
|
|
// A declaration directly contained in a linkage-specification is treated
|
|
|
|
// as if it contains the extern specifier for the purpose of determining
|
|
|
|
// the linkage of the declared name and whether it is a definition.
|
2015-04-16 07:04:24 +08:00
|
|
|
if (isSingleLineLanguageLinkage(*this))
|
2013-04-26 09:30:23 +08:00
|
|
|
return DeclarationOnly;
|
2013-04-25 20:11:36 +08:00
|
|
|
|
2010-02-01 06:27:38 +08:00
|
|
|
// C99 6.9.2p2:
|
|
|
|
// A declaration of an object that has file scope without an initializer,
|
|
|
|
// and without a storage class specifier or the scs 'static', constitutes
|
|
|
|
// a tentative definition.
|
|
|
|
// No such thing in C++.
|
2012-03-11 15:00:24 +08:00
|
|
|
if (!C.getLangOpts().CPlusPlus && isFileVarDecl())
|
2010-02-01 06:27:38 +08:00
|
|
|
return TentativeDefinition;
|
|
|
|
|
|
|
|
// What's left is (in C, block-scope) declarations without initializers or
|
|
|
|
// external storage. These are definitions.
|
|
|
|
return Definition;
|
|
|
|
}
|
|
|
|
|
|
|
|
VarDecl *VarDecl::getActingDefinition() {
|
|
|
|
DefinitionKind Kind = isThisDeclarationADefinition();
|
|
|
|
if (Kind != TentativeDefinition)
|
2014-05-12 13:36:57 +08:00
|
|
|
return nullptr;
|
2010-02-01 06:27:38 +08:00
|
|
|
|
2014-05-12 13:36:57 +08:00
|
|
|
VarDecl *LastTentative = nullptr;
|
2013-10-17 23:37:26 +08:00
|
|
|
VarDecl *First = getFirstDecl();
|
2014-03-07 07:45:36 +08:00
|
|
|
for (auto I : First->redecls()) {
|
|
|
|
Kind = I->isThisDeclarationADefinition();
|
2010-02-01 06:27:38 +08:00
|
|
|
if (Kind == Definition)
|
2014-05-12 13:36:57 +08:00
|
|
|
return nullptr;
|
2010-02-01 06:27:38 +08:00
|
|
|
else if (Kind == TentativeDefinition)
|
2014-03-07 07:45:36 +08:00
|
|
|
LastTentative = I;
|
2010-02-01 06:27:38 +08:00
|
|
|
}
|
|
|
|
return LastTentative;
|
|
|
|
}
|
|
|
|
|
2012-03-09 09:51:51 +08:00
|
|
|
VarDecl *VarDecl::getDefinition(ASTContext &C) {
|
2013-10-17 23:37:26 +08:00
|
|
|
VarDecl *First = getFirstDecl();
|
2014-03-07 07:45:36 +08:00
|
|
|
for (auto I : First->redecls()) {
|
|
|
|
if (I->isThisDeclarationADefinition(C) == Definition)
|
|
|
|
return I;
|
2010-02-02 04:16:42 +08:00
|
|
|
}
|
2014-05-12 13:36:57 +08:00
|
|
|
return nullptr;
|
2010-02-01 06:27:38 +08:00
|
|
|
}
|
|
|
|
|
2012-03-09 09:51:51 +08:00
|
|
|
VarDecl::DefinitionKind VarDecl::hasDefinition(ASTContext &C) const {
|
2010-10-30 06:22:43 +08:00
|
|
|
DefinitionKind Kind = DeclarationOnly;
|
|
|
|
|
2013-10-17 23:37:26 +08:00
|
|
|
const VarDecl *First = getFirstDecl();
|
2014-03-07 07:45:36 +08:00
|
|
|
for (auto I : First->redecls()) {
|
|
|
|
Kind = std::max(Kind, I->isThisDeclarationADefinition(C));
|
2012-03-07 07:52:46 +08:00
|
|
|
if (Kind == Definition)
|
|
|
|
break;
|
|
|
|
}
|
2010-10-30 06:22:43 +08:00
|
|
|
|
|
|
|
return Kind;
|
|
|
|
}
|
|
|
|
|
2010-02-02 04:16:42 +08:00
|
|
|
const Expr *VarDecl::getAnyInitializer(const VarDecl *&D) const {
|
2014-03-07 07:45:36 +08:00
|
|
|
for (auto I : redecls()) {
|
|
|
|
if (auto Expr = I->getInit()) {
|
|
|
|
D = I;
|
|
|
|
return Expr;
|
|
|
|
}
|
2010-01-27 06:01:41 +08:00
|
|
|
}
|
2014-05-12 13:36:57 +08:00
|
|
|
return nullptr;
|
2010-01-27 06:01:41 +08:00
|
|
|
}
|
|
|
|
|
2009-10-15 05:29:40 +08:00
|
|
|
bool VarDecl::isOutOfLine() const {
|
2011-02-20 02:51:44 +08:00
|
|
|
if (Decl::isOutOfLine())
|
2009-10-15 05:29:40 +08:00
|
|
|
return true;
|
2010-02-21 15:08:09 +08:00
|
|
|
|
|
|
|
if (!isStaticDataMember())
|
|
|
|
return false;
|
|
|
|
|
2009-10-15 05:29:40 +08:00
|
|
|
// If this static data member was instantiated from a static data member of
|
|
|
|
// a class template, check whether that static data member was defined
|
|
|
|
// out-of-line.
|
|
|
|
if (VarDecl *VD = getInstantiatedFromStaticDataMember())
|
|
|
|
return VD->isOutOfLine();
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-10-28 02:42:08 +08:00
|
|
|
VarDecl *VarDecl::getOutOfLineDefinition() {
|
|
|
|
if (!isStaticDataMember())
|
2014-05-12 13:36:57 +08:00
|
|
|
return nullptr;
|
|
|
|
|
2014-03-07 07:45:36 +08:00
|
|
|
for (auto RD : redecls()) {
|
2009-10-28 02:42:08 +08:00
|
|
|
if (RD->getLexicalDeclContext()->isFileContext())
|
2014-03-07 07:45:36 +08:00
|
|
|
return RD;
|
2009-10-28 02:42:08 +08:00
|
|
|
}
|
2014-05-12 13:36:57 +08:00
|
|
|
|
|
|
|
return nullptr;
|
2009-10-28 02:42:08 +08:00
|
|
|
}
|
|
|
|
|
2010-02-11 09:19:42 +08:00
|
|
|
void VarDecl::setInit(Expr *I) {
|
2010-01-27 06:01:41 +08:00
|
|
|
if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) {
|
|
|
|
Eval->~EvaluatedStmt();
|
2010-02-11 09:19:42 +08:00
|
|
|
getASTContext().Deallocate(Eval);
|
2010-01-27 06:01:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Init = I;
|
|
|
|
}
|
|
|
|
|
2012-03-09 09:51:51 +08:00
|
|
|
bool VarDecl::isUsableInConstantExpressions(ASTContext &C) const {
|
2012-03-11 15:00:24 +08:00
|
|
|
const LangOptions &Lang = C.getLangOpts();
|
2011-12-21 10:55:12 +08:00
|
|
|
|
2012-03-02 12:14:40 +08:00
|
|
|
if (!Lang.CPlusPlus)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// In C++11, any variable of reference type can be used in a constant
|
|
|
|
// expression if it is initialized by a constant expression.
|
2013-01-02 19:42:31 +08:00
|
|
|
if (Lang.CPlusPlus11 && getType()->isReferenceType())
|
2012-03-02 12:14:40 +08:00
|
|
|
return true;
|
|
|
|
|
|
|
|
// Only const objects can be used in constant expressions in C++. C++98 does
|
2011-12-21 10:55:12 +08:00
|
|
|
// not require the variable to be non-volatile, but we consider this to be a
|
|
|
|
// defect.
|
2012-03-02 12:14:40 +08:00
|
|
|
if (!getType().isConstQualified() || getType().isVolatileQualified())
|
2011-12-21 10:55:12 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// In C++, const, non-volatile variables of integral or enumeration types
|
|
|
|
// can be used in constant expressions.
|
|
|
|
if (getType()->isIntegralOrEnumerationType())
|
|
|
|
return true;
|
|
|
|
|
2012-03-02 12:14:40 +08:00
|
|
|
// Additionally, in C++11, non-volatile constexpr variables can be used in
|
|
|
|
// constant expressions.
|
2013-01-02 19:42:31 +08:00
|
|
|
return Lang.CPlusPlus11 && isConstexpr();
|
2011-12-21 10:55:12 +08:00
|
|
|
}
|
|
|
|
|
2011-12-19 14:19:21 +08:00
|
|
|
/// Convert the initializer for this declaration to the elaborated EvaluatedStmt
|
|
|
|
/// form, which contains extra information on the evaluated value of the
|
|
|
|
/// initializer.
|
|
|
|
EvaluatedStmt *VarDecl::ensureEvaluatedStmt() const {
|
|
|
|
EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>();
|
|
|
|
if (!Eval) {
|
|
|
|
Stmt *S = Init.get<Stmt *>();
|
2013-06-03 21:51:33 +08:00
|
|
|
// Note: EvaluatedStmt contains an APValue, which usually holds
|
|
|
|
// resources not allocated from the ASTContext. We need to do some
|
|
|
|
// work to avoid leaking those, but we do so in VarDecl::evaluateValue
|
|
|
|
// where we can detect whether there's anything to clean up or not.
|
2011-12-19 14:19:21 +08:00
|
|
|
Eval = new (getASTContext()) EvaluatedStmt;
|
|
|
|
Eval->Value = S;
|
|
|
|
Init = Eval;
|
|
|
|
}
|
|
|
|
return Eval;
|
|
|
|
}
|
|
|
|
|
2012-01-14 12:30:29 +08:00
|
|
|
APValue *VarDecl::evaluateValue() const {
|
2013-01-13 03:30:44 +08:00
|
|
|
SmallVector<PartialDiagnosticAt, 8> Notes;
|
2012-01-14 12:30:29 +08:00
|
|
|
return evaluateValue(Notes);
|
|
|
|
}
|
|
|
|
|
2013-06-03 21:51:33 +08:00
|
|
|
namespace {
|
|
|
|
// Destroy an APValue that was allocated in an ASTContext.
|
|
|
|
void DestroyAPValue(void* UntypedValue) {
|
|
|
|
static_cast<APValue*>(UntypedValue)->~APValue();
|
|
|
|
}
|
|
|
|
} // namespace
|
|
|
|
|
2012-01-14 12:30:29 +08:00
|
|
|
APValue *VarDecl::evaluateValue(
|
2013-01-13 03:30:44 +08:00
|
|
|
SmallVectorImpl<PartialDiagnosticAt> &Notes) const {
|
2011-12-19 14:19:21 +08:00
|
|
|
EvaluatedStmt *Eval = ensureEvaluatedStmt();
|
|
|
|
|
|
|
|
// We only produce notes indicating why an initializer is non-constant the
|
|
|
|
// first time it is evaluated. FIXME: The notes won't always be emitted the
|
|
|
|
// first time we try evaluation, so might not be produced at all.
|
|
|
|
if (Eval->WasEvaluated)
|
2014-05-12 13:36:57 +08:00
|
|
|
return Eval->Evaluated.isUninit() ? nullptr : &Eval->Evaluated;
|
2011-12-19 14:19:21 +08:00
|
|
|
|
|
|
|
const Expr *Init = cast<Expr>(Eval->Value);
|
|
|
|
assert(!Init->isValueDependent());
|
|
|
|
|
|
|
|
if (Eval->IsEvaluating) {
|
|
|
|
// FIXME: Produce a diagnostic for self-initialization.
|
|
|
|
Eval->CheckedICE = true;
|
|
|
|
Eval->IsICE = false;
|
2014-05-12 13:36:57 +08:00
|
|
|
return nullptr;
|
2011-12-19 14:19:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Eval->IsEvaluating = true;
|
|
|
|
|
|
|
|
bool Result = Init->EvaluateAsInitializer(Eval->Evaluated, getASTContext(),
|
|
|
|
this, Notes);
|
|
|
|
|
2013-06-03 21:51:33 +08:00
|
|
|
// Ensure the computed APValue is cleaned up later if evaluation succeeded,
|
|
|
|
// or that it's empty (so that there's nothing to clean up) if evaluation
|
|
|
|
// failed.
|
2011-12-19 14:19:21 +08:00
|
|
|
if (!Result)
|
|
|
|
Eval->Evaluated = APValue();
|
2013-06-03 21:51:33 +08:00
|
|
|
else if (Eval->Evaluated.needsCleanup())
|
|
|
|
getASTContext().AddDeallocation(DestroyAPValue, &Eval->Evaluated);
|
2011-12-19 14:19:21 +08:00
|
|
|
|
|
|
|
Eval->IsEvaluating = false;
|
|
|
|
Eval->WasEvaluated = true;
|
|
|
|
|
|
|
|
// In C++11, we have determined whether the initializer was a constant
|
|
|
|
// expression as a side-effect.
|
2013-01-02 19:42:31 +08:00
|
|
|
if (getASTContext().getLangOpts().CPlusPlus11 && !Eval->CheckedICE) {
|
2011-12-19 14:19:21 +08:00
|
|
|
Eval->CheckedICE = true;
|
2012-02-07 05:50:18 +08:00
|
|
|
Eval->IsICE = Result && Notes.empty();
|
2011-12-19 14:19:21 +08:00
|
|
|
}
|
|
|
|
|
2014-05-12 13:36:57 +08:00
|
|
|
return Result ? &Eval->Evaluated : nullptr;
|
2011-12-19 14:19:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool VarDecl::checkInitIsICE() const {
|
2012-01-05 08:13:19 +08:00
|
|
|
// Initializers of weak variables are never ICEs.
|
|
|
|
if (isWeak())
|
|
|
|
return false;
|
|
|
|
|
2011-12-19 14:19:21 +08:00
|
|
|
EvaluatedStmt *Eval = ensureEvaluatedStmt();
|
|
|
|
if (Eval->CheckedICE)
|
|
|
|
// We have already checked whether this subexpression is an
|
|
|
|
// integral constant expression.
|
|
|
|
return Eval->IsICE;
|
|
|
|
|
|
|
|
const Expr *Init = cast<Expr>(Eval->Value);
|
|
|
|
assert(!Init->isValueDependent());
|
|
|
|
|
|
|
|
// In C++11, evaluate the initializer to check whether it's a constant
|
|
|
|
// expression.
|
2013-01-02 19:42:31 +08:00
|
|
|
if (getASTContext().getLangOpts().CPlusPlus11) {
|
2013-01-13 03:30:44 +08:00
|
|
|
SmallVector<PartialDiagnosticAt, 8> Notes;
|
2011-12-19 14:19:21 +08:00
|
|
|
evaluateValue(Notes);
|
|
|
|
return Eval->IsICE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// It's an ICE whether or not the definition we found is
|
|
|
|
// out-of-line. See DR 721 and the discussion in Clang PR
|
|
|
|
// 6206 for details.
|
|
|
|
|
|
|
|
if (Eval->CheckingICE)
|
|
|
|
return false;
|
|
|
|
Eval->CheckingICE = true;
|
|
|
|
|
|
|
|
Eval->IsICE = Init->isIntegerConstantExpr(getASTContext());
|
|
|
|
Eval->CheckingICE = false;
|
|
|
|
Eval->CheckedICE = true;
|
|
|
|
return Eval->IsICE;
|
|
|
|
}
|
|
|
|
|
2009-10-15 05:29:40 +08:00
|
|
|
VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const {
|
2009-10-13 04:18:28 +08:00
|
|
|
if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
|
2009-10-08 15:24:58 +08:00
|
|
|
return cast<VarDecl>(MSI->getInstantiatedFrom());
|
2014-05-12 13:36:57 +08:00
|
|
|
|
|
|
|
return nullptr;
|
2009-10-08 15:24:58 +08:00
|
|
|
}
|
|
|
|
|
2009-10-15 04:14:33 +08:00
|
|
|
TemplateSpecializationKind VarDecl::getTemplateSpecializationKind() const {
|
2013-08-06 09:03:05 +08:00
|
|
|
if (const VarTemplateSpecializationDecl *Spec =
|
|
|
|
dyn_cast<VarTemplateSpecializationDecl>(this))
|
|
|
|
return Spec->getSpecializationKind();
|
|
|
|
|
2010-02-01 06:27:38 +08:00
|
|
|
if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
|
2009-10-08 15:24:58 +08:00
|
|
|
return MSI->getTemplateSpecializationKind();
|
2013-09-28 04:14:12 +08:00
|
|
|
|
2009-10-08 15:24:58 +08:00
|
|
|
return TSK_Undeclared;
|
|
|
|
}
|
|
|
|
|
2013-09-28 04:14:12 +08:00
|
|
|
SourceLocation VarDecl::getPointOfInstantiation() const {
|
|
|
|
if (const VarTemplateSpecializationDecl *Spec =
|
|
|
|
dyn_cast<VarTemplateSpecializationDecl>(this))
|
|
|
|
return Spec->getPointOfInstantiation();
|
|
|
|
|
|
|
|
if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
|
|
|
|
return MSI->getPointOfInstantiation();
|
|
|
|
|
|
|
|
return SourceLocation();
|
|
|
|
}
|
|
|
|
|
2013-08-06 09:03:05 +08:00
|
|
|
VarTemplateDecl *VarDecl::getDescribedVarTemplate() const {
|
|
|
|
return getASTContext().getTemplateOrSpecializationInfo(this)
|
|
|
|
.dyn_cast<VarTemplateDecl *>();
|
|
|
|
}
|
|
|
|
|
|
|
|
void VarDecl::setDescribedVarTemplate(VarTemplateDecl *Template) {
|
|
|
|
getASTContext().setTemplateOrSpecializationInfo(this, Template);
|
|
|
|
}
|
|
|
|
|
2009-10-15 05:29:40 +08:00
|
|
|
MemberSpecializationInfo *VarDecl::getMemberSpecializationInfo() const {
|
2013-08-01 12:12:04 +08:00
|
|
|
if (isStaticDataMember())
|
2013-08-06 09:03:05 +08:00
|
|
|
// FIXME: Remove ?
|
|
|
|
// return getASTContext().getInstantiatedFromStaticDataMember(this);
|
|
|
|
return getASTContext().getTemplateOrSpecializationInfo(this)
|
|
|
|
.dyn_cast<MemberSpecializationInfo *>();
|
2014-05-12 13:36:57 +08:00
|
|
|
return nullptr;
|
2009-10-13 04:18:28 +08:00
|
|
|
}
|
|
|
|
|
2009-10-16 01:21:20 +08:00
|
|
|
void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
|
|
|
|
SourceLocation PointOfInstantiation) {
|
2013-09-28 04:14:12 +08:00
|
|
|
assert((isa<VarTemplateSpecializationDecl>(this) ||
|
|
|
|
getMemberSpecializationInfo()) &&
|
|
|
|
"not a variable or static data member template specialization");
|
|
|
|
|
2013-08-06 09:03:05 +08:00
|
|
|
if (VarTemplateSpecializationDecl *Spec =
|
|
|
|
dyn_cast<VarTemplateSpecializationDecl>(this)) {
|
|
|
|
Spec->setSpecializationKind(TSK);
|
|
|
|
if (TSK != TSK_ExplicitSpecialization && PointOfInstantiation.isValid() &&
|
|
|
|
Spec->getPointOfInstantiation().isInvalid())
|
|
|
|
Spec->setPointOfInstantiation(PointOfInstantiation);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) {
|
|
|
|
MSI->setTemplateSpecializationKind(TSK);
|
|
|
|
if (TSK != TSK_ExplicitSpecialization && PointOfInstantiation.isValid() &&
|
|
|
|
MSI->getPointOfInstantiation().isInvalid())
|
|
|
|
MSI->setPointOfInstantiation(PointOfInstantiation);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
VarDecl::setInstantiationOfStaticDataMember(VarDecl *VD,
|
|
|
|
TemplateSpecializationKind TSK) {
|
|
|
|
assert(getASTContext().getTemplateOrSpecializationInfo(this).isNull() &&
|
|
|
|
"Previous template or instantiation?");
|
|
|
|
getASTContext().setInstantiatedFromStaticDataMember(this, VD, TSK);
|
2009-07-25 04:34:43 +08:00
|
|
|
}
|
|
|
|
|
2010-01-27 06:01:41 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// ParmVarDecl Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
2009-03-11 07:43:53 +08:00
|
|
|
|
2010-01-27 06:01:41 +08:00
|
|
|
ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC,
|
2011-03-08 16:55:46 +08:00
|
|
|
SourceLocation StartLoc,
|
|
|
|
SourceLocation IdLoc, IdentifierInfo *Id,
|
2010-01-27 06:01:41 +08:00
|
|
|
QualType T, TypeSourceInfo *TInfo,
|
2013-04-04 03:27:57 +08:00
|
|
|
StorageClass S, Expr *DefArg) {
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
return new (C, DC) ParmVarDecl(ParmVar, C, DC, StartLoc, IdLoc, Id, T, TInfo,
|
2013-11-22 17:01:48 +08:00
|
|
|
S, DefArg);
|
2009-03-11 07:43:53 +08:00
|
|
|
}
|
|
|
|
|
2013-06-25 01:51:48 +08:00
|
|
|
QualType ParmVarDecl::getOriginalType() const {
|
|
|
|
TypeSourceInfo *TSI = getTypeSourceInfo();
|
|
|
|
QualType T = TSI ? TSI->getType() : getType();
|
|
|
|
if (const DecayedType *DT = dyn_cast<DecayedType>(T))
|
|
|
|
return DT->getOriginalType();
|
|
|
|
return T;
|
|
|
|
}
|
|
|
|
|
2012-01-06 05:55:30 +08:00
|
|
|
ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
return new (C, ID)
|
|
|
|
ParmVarDecl(ParmVar, C, nullptr, SourceLocation(), SourceLocation(),
|
|
|
|
nullptr, QualType(), nullptr, SC_None, nullptr);
|
2012-01-06 05:55:30 +08:00
|
|
|
}
|
|
|
|
|
2011-07-31 01:23:26 +08:00
|
|
|
SourceRange ParmVarDecl::getSourceRange() const {
|
|
|
|
if (!hasInheritedDefaultArg()) {
|
|
|
|
SourceRange ArgRange = getDefaultArgRange();
|
|
|
|
if (ArgRange.isValid())
|
|
|
|
return SourceRange(getOuterLocStart(), ArgRange.getEnd());
|
|
|
|
}
|
|
|
|
|
2013-04-17 09:56:48 +08:00
|
|
|
// DeclaratorDecl considers the range of postfix types as overlapping with the
|
|
|
|
// declaration name, but this is not the case with parameters in ObjC methods.
|
|
|
|
if (isa<ObjCMethodDecl>(getDeclContext()))
|
|
|
|
return SourceRange(DeclaratorDecl::getLocStart(), getLocation());
|
|
|
|
|
2011-07-31 01:23:26 +08:00
|
|
|
return DeclaratorDecl::getSourceRange();
|
|
|
|
}
|
|
|
|
|
2010-01-27 06:01:41 +08:00
|
|
|
Expr *ParmVarDecl::getDefaultArg() {
|
|
|
|
assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!");
|
|
|
|
assert(!hasUninstantiatedDefaultArg() &&
|
|
|
|
"Default argument is not yet instantiated!");
|
|
|
|
|
|
|
|
Expr *Arg = getInit();
|
2010-12-06 16:20:24 +08:00
|
|
|
if (ExprWithCleanups *E = dyn_cast_or_null<ExprWithCleanups>(Arg))
|
2010-01-27 06:01:41 +08:00
|
|
|
return E->getSubExpr();
|
|
|
|
|
|
|
|
return Arg;
|
|
|
|
}
|
|
|
|
|
|
|
|
SourceRange ParmVarDecl::getDefaultArgRange() const {
|
|
|
|
if (const Expr *E = getInit())
|
|
|
|
return E->getSourceRange();
|
|
|
|
|
|
|
|
if (hasUninstantiatedDefaultArg())
|
|
|
|
return getUninstantiatedDefaultArg()->getSourceRange();
|
|
|
|
|
|
|
|
return SourceRange();
|
2009-07-06 06:21:56 +08:00
|
|
|
}
|
|
|
|
|
2011-01-06 05:11:38 +08:00
|
|
|
bool ParmVarDecl::isParameterPack() const {
|
|
|
|
return isa<PackExpansionType>(getType());
|
|
|
|
}
|
|
|
|
|
2011-10-06 13:00:56 +08:00
|
|
|
void ParmVarDecl::setParameterIndexLarge(unsigned parameterIndex) {
|
|
|
|
getASTContext().setParameterIndex(this, parameterIndex);
|
|
|
|
ParmVarDeclBits.ParameterIndex = ParameterIndexSentinel;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned ParmVarDecl::getParameterIndexLarge() const {
|
|
|
|
return getASTContext().getParameterIndex(this);
|
|
|
|
}
|
|
|
|
|
2008-11-10 07:41:00 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2008-03-31 08:36:02 +08:00
|
|
|
// FunctionDecl Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2013-02-22 23:46:01 +08:00
|
|
|
void FunctionDecl::getNameForDiagnostic(
|
|
|
|
raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
|
|
|
|
NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
|
2011-02-20 02:51:44 +08:00
|
|
|
const TemplateArgumentList *TemplateArgs = getTemplateSpecializationArgs();
|
|
|
|
if (TemplateArgs)
|
2013-02-22 23:46:01 +08:00
|
|
|
TemplateSpecializationType::PrintTemplateArgumentList(
|
|
|
|
OS, TemplateArgs->data(), TemplateArgs->size(), Policy);
|
2011-02-20 02:51:44 +08:00
|
|
|
}
|
|
|
|
|
2010-04-30 00:49:01 +08:00
|
|
|
bool FunctionDecl::isVariadic() const {
|
|
|
|
if (const FunctionProtoType *FT = getType()->getAs<FunctionProtoType>())
|
|
|
|
return FT->isVariadic();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-07-07 19:31:19 +08:00
|
|
|
bool FunctionDecl::hasBody(const FunctionDecl *&Definition) const {
|
2014-03-07 07:45:36 +08:00
|
|
|
for (auto I : redecls()) {
|
2011-04-23 06:18:13 +08:00
|
|
|
if (I->Body || I->IsLateTemplateParsed) {
|
2014-03-07 07:45:36 +08:00
|
|
|
Definition = I;
|
2010-07-07 19:31:19 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-05-15 07:26:09 +08:00
|
|
|
bool FunctionDecl::hasTrivialBody() const
|
|
|
|
{
|
|
|
|
Stmt *S = getBody();
|
|
|
|
if (!S) {
|
|
|
|
// Since we don't have a body for this function, we don't know if it's
|
|
|
|
// trivial or not.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isa<CompoundStmt>(S) && cast<CompoundStmt>(S)->body_empty())
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-05-07 04:44:56 +08:00
|
|
|
bool FunctionDecl::isDefined(const FunctionDecl *&Definition) const {
|
2014-03-07 07:45:36 +08:00
|
|
|
for (auto I : redecls()) {
|
2013-10-23 05:39:03 +08:00
|
|
|
if (I->IsDeleted || I->IsDefaulted || I->Body || I->IsLateTemplateParsed ||
|
|
|
|
I->hasAttr<AliasAttr>()) {
|
2014-03-07 07:45:36 +08:00
|
|
|
Definition = I->IsDeleted ? I->getCanonicalDecl() : I;
|
2011-05-07 04:44:56 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-06-30 10:35:26 +08:00
|
|
|
Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
|
2013-10-19 09:37:17 +08:00
|
|
|
if (!hasBody(Definition))
|
2014-05-12 13:36:57 +08:00
|
|
|
return nullptr;
|
2013-10-19 09:37:17 +08:00
|
|
|
|
|
|
|
if (Definition->Body)
|
|
|
|
return Definition->Body.get(getASTContext().getExternalSource());
|
2008-04-21 10:02:58 +08:00
|
|
|
|
2014-05-12 13:36:57 +08:00
|
|
|
return nullptr;
|
2007-01-21 15:42:07 +08:00
|
|
|
}
|
|
|
|
|
2009-06-20 16:09:14 +08:00
|
|
|
void FunctionDecl::setBody(Stmt *B) {
|
|
|
|
Body = B;
|
2010-12-07 01:49:01 +08:00
|
|
|
if (B)
|
2009-06-20 16:09:14 +08:00
|
|
|
EndRangeLoc = B->getLocEnd();
|
|
|
|
}
|
|
|
|
|
2010-09-29 05:55:22 +08:00
|
|
|
void FunctionDecl::setPure(bool P) {
|
|
|
|
IsPure = P;
|
|
|
|
if (P)
|
|
|
|
if (CXXRecordDecl *Parent = dyn_cast<CXXRecordDecl>(getDeclContext()))
|
|
|
|
Parent->markedVirtualFunctionPure();
|
|
|
|
}
|
|
|
|
|
2013-07-22 07:12:18 +08:00
|
|
|
template<std::size_t Len>
|
|
|
|
static bool isNamed(const NamedDecl *ND, const char (&Str)[Len]) {
|
|
|
|
IdentifierInfo *II = ND->getIdentifier();
|
|
|
|
return II && II->isStr(Str);
|
|
|
|
}
|
|
|
|
|
2009-09-12 08:17:51 +08:00
|
|
|
bool FunctionDecl::isMain() const {
|
2011-05-16 01:49:20 +08:00
|
|
|
const TranslationUnitDecl *tunit =
|
|
|
|
dyn_cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext());
|
|
|
|
return tunit &&
|
2012-03-11 15:00:24 +08:00
|
|
|
!tunit->getASTContext().getLangOpts().Freestanding &&
|
2013-07-22 07:12:18 +08:00
|
|
|
isNamed(this, "main");
|
2011-05-16 01:49:20 +08:00
|
|
|
}
|
|
|
|
|
2013-09-17 06:44:20 +08:00
|
|
|
bool FunctionDecl::isMSVCRTEntryPoint() const {
|
|
|
|
const TranslationUnitDecl *TUnit =
|
|
|
|
dyn_cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext());
|
|
|
|
if (!TUnit)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Even though we aren't really targeting MSVCRT if we are freestanding,
|
|
|
|
// semantic analysis for these functions remains the same.
|
|
|
|
|
|
|
|
// MSVCRT entry points only exist on MSVCRT targets.
|
|
|
|
if (!TUnit->getASTContext().getTargetInfo().getTriple().isOSMSVCRT())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Nameless functions like constructors cannot be entry points.
|
|
|
|
if (!getIdentifier())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return llvm::StringSwitch<bool>(getName())
|
|
|
|
.Cases("main", // an ANSI console app
|
|
|
|
"wmain", // a Unicode console App
|
|
|
|
"WinMain", // an ANSI GUI app
|
|
|
|
"wWinMain", // a Unicode GUI app
|
|
|
|
"DllMain", // a DLL
|
|
|
|
true)
|
|
|
|
.Default(false);
|
|
|
|
}
|
|
|
|
|
2011-05-16 01:49:20 +08:00
|
|
|
bool FunctionDecl::isReservedGlobalPlacementOperator() const {
|
|
|
|
assert(getDeclName().getNameKind() == DeclarationName::CXXOperatorName);
|
|
|
|
assert(getDeclName().getCXXOverloadedOperator() == OO_New ||
|
|
|
|
getDeclName().getCXXOverloadedOperator() == OO_Delete ||
|
|
|
|
getDeclName().getCXXOverloadedOperator() == OO_Array_New ||
|
|
|
|
getDeclName().getCXXOverloadedOperator() == OO_Array_Delete);
|
|
|
|
|
2014-01-20 07:25:37 +08:00
|
|
|
if (!getDeclContext()->getRedeclContext()->isTranslationUnit())
|
|
|
|
return false;
|
2011-05-16 01:49:20 +08:00
|
|
|
|
|
|
|
const FunctionProtoType *proto = getType()->castAs<FunctionProtoType>();
|
2014-01-21 04:26:09 +08:00
|
|
|
if (proto->getNumParams() != 2 || proto->isVariadic())
|
|
|
|
return false;
|
2011-05-16 01:49:20 +08:00
|
|
|
|
|
|
|
ASTContext &Context =
|
|
|
|
cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext())
|
|
|
|
->getASTContext();
|
|
|
|
|
|
|
|
// The result type and first argument type are constant across all
|
|
|
|
// these operators. The second argument must be exactly void*.
|
2014-01-21 04:26:09 +08:00
|
|
|
return (proto->getParamType(1).getCanonicalType() == Context.VoidPtrTy);
|
2009-02-24 09:23:02 +08:00
|
|
|
}
|
|
|
|
|
2013-07-22 07:12:18 +08:00
|
|
|
bool FunctionDecl::isReplaceableGlobalAllocationFunction() const {
|
|
|
|
if (getDeclName().getNameKind() != DeclarationName::CXXOperatorName)
|
|
|
|
return false;
|
|
|
|
if (getDeclName().getCXXOverloadedOperator() != OO_New &&
|
|
|
|
getDeclName().getCXXOverloadedOperator() != OO_Delete &&
|
|
|
|
getDeclName().getCXXOverloadedOperator() != OO_Array_New &&
|
|
|
|
getDeclName().getCXXOverloadedOperator() != OO_Array_Delete)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (isa<CXXRecordDecl>(getDeclContext()))
|
|
|
|
return false;
|
2014-01-20 07:25:37 +08:00
|
|
|
|
|
|
|
// This can only fail for an invalid 'operator new' declaration.
|
|
|
|
if (!getDeclContext()->getRedeclContext()->isTranslationUnit())
|
|
|
|
return false;
|
2013-07-22 07:12:18 +08:00
|
|
|
|
|
|
|
const FunctionProtoType *FPT = getType()->castAs<FunctionProtoType>();
|
2014-06-07 08:43:57 +08:00
|
|
|
if (FPT->getNumParams() == 0 || FPT->getNumParams() > 2 || FPT->isVariadic())
|
2013-07-22 07:12:18 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// If this is a single-parameter function, it must be a replaceable global
|
|
|
|
// allocation or deallocation function.
|
2014-01-21 04:26:09 +08:00
|
|
|
if (FPT->getNumParams() == 1)
|
2013-07-22 07:12:18 +08:00
|
|
|
return true;
|
|
|
|
|
|
|
|
// Otherwise, we're looking for a second parameter whose type is
|
2013-09-29 12:40:38 +08:00
|
|
|
// 'const std::nothrow_t &', or, in C++1y, 'std::size_t'.
|
2014-01-21 04:26:09 +08:00
|
|
|
QualType Ty = FPT->getParamType(1);
|
2013-09-29 12:40:38 +08:00
|
|
|
ASTContext &Ctx = getASTContext();
|
2013-11-05 17:12:18 +08:00
|
|
|
if (Ctx.getLangOpts().SizedDeallocation &&
|
|
|
|
Ctx.hasSameType(Ty, Ctx.getSizeType()))
|
2013-09-29 12:40:38 +08:00
|
|
|
return true;
|
2013-07-22 07:12:18 +08:00
|
|
|
if (!Ty->isReferenceType())
|
|
|
|
return false;
|
|
|
|
Ty = Ty->getPointeeType();
|
|
|
|
if (Ty.getCVRQualifiers() != Qualifiers::Const)
|
|
|
|
return false;
|
|
|
|
const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
|
2014-05-28 10:16:01 +08:00
|
|
|
return RD && isNamed(RD, "nothrow_t") && RD->isInStdNamespace();
|
2013-07-22 07:12:18 +08:00
|
|
|
}
|
|
|
|
|
2013-02-14 09:18:37 +08:00
|
|
|
LanguageLinkage FunctionDecl::getLanguageLinkage() const {
|
2014-05-31 14:11:02 +08:00
|
|
|
return getDeclLanguageLinkage(*this);
|
2012-12-28 22:21:58 +08:00
|
|
|
}
|
|
|
|
|
2013-03-14 11:07:35 +08:00
|
|
|
bool FunctionDecl::isExternC() const {
|
2014-05-31 14:11:02 +08:00
|
|
|
return isDeclExternC(*this);
|
2013-05-06 04:15:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool FunctionDecl::isInExternCContext() const {
|
2013-11-14 10:13:03 +08:00
|
|
|
return getLexicalDeclContext()->isExternCContext();
|
2013-05-06 04:15:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool FunctionDecl::isInExternCXXContext() const {
|
2013-11-14 10:13:03 +08:00
|
|
|
return getLexicalDeclContext()->isExternCXXContext();
|
2013-03-14 11:07:35 +08:00
|
|
|
}
|
|
|
|
|
2009-04-01 00:35:03 +08:00
|
|
|
bool FunctionDecl::isGlobal() const {
|
|
|
|
if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(this))
|
|
|
|
return Method->isStatic();
|
|
|
|
|
2013-04-04 03:27:57 +08:00
|
|
|
if (getCanonicalDecl()->getStorageClass() == SC_Static)
|
2009-04-01 00:35:03 +08:00
|
|
|
return false;
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
for (const DeclContext *DC = getDeclContext();
|
2009-04-01 00:35:03 +08:00
|
|
|
DC->isNamespace();
|
|
|
|
DC = DC->getParent()) {
|
|
|
|
if (const NamespaceDecl *Namespace = cast<NamespaceDecl>(DC)) {
|
|
|
|
if (!Namespace->getDeclName())
|
|
|
|
return false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-01-17 09:30:42 +08:00
|
|
|
bool FunctionDecl::isNoReturn() const {
|
|
|
|
return hasAttr<NoReturnAttr>() || hasAttr<CXX11NoReturnAttr>() ||
|
2013-01-30 13:45:05 +08:00
|
|
|
hasAttr<C11NoReturnAttr>() ||
|
2013-01-17 09:30:42 +08:00
|
|
|
getType()->getAs<FunctionType>()->getNoReturnAttr();
|
|
|
|
}
|
|
|
|
|
2010-01-27 06:01:41 +08:00
|
|
|
void
|
|
|
|
FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) {
|
2013-10-17 23:37:26 +08:00
|
|
|
redeclarable_base::setPreviousDecl(PrevDecl);
|
2010-01-27 06:01:41 +08:00
|
|
|
|
|
|
|
if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) {
|
|
|
|
FunctionTemplateDecl *PrevFunTmpl
|
2014-05-12 13:36:57 +08:00
|
|
|
= PrevDecl? PrevDecl->getDescribedFunctionTemplate() : nullptr;
|
2010-01-27 06:01:41 +08:00
|
|
|
assert((!PrevDecl || PrevFunTmpl) && "Function/function template mismatch");
|
2013-10-17 23:37:26 +08:00
|
|
|
FunTmpl->setPreviousDecl(PrevFunTmpl);
|
2010-01-27 06:01:41 +08:00
|
|
|
}
|
2010-12-10 00:59:22 +08:00
|
|
|
|
2011-11-09 02:21:06 +08:00
|
|
|
if (PrevDecl && PrevDecl->IsInline)
|
2010-12-10 00:59:22 +08:00
|
|
|
IsInline = true;
|
2010-01-27 06:01:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
const FunctionDecl *FunctionDecl::getCanonicalDecl() const {
|
2013-10-17 23:37:26 +08:00
|
|
|
return getFirstDecl();
|
2010-01-27 06:01:41 +08:00
|
|
|
}
|
|
|
|
|
2013-10-17 23:37:26 +08:00
|
|
|
FunctionDecl *FunctionDecl::getCanonicalDecl() { return getFirstDecl(); }
|
2010-01-27 06:01:41 +08:00
|
|
|
|
Implicitly declare certain C library functions (malloc, strcpy, memmove,
etc.) when we perform name lookup on them. This ensures that we
produce the correct signature for these functions, which has two
practical impacts:
1) When we're supporting the "implicit function declaration" feature
of C99, these functions will be implicitly declared with the right
signature rather than as a function returning "int" with no
prototype. See PR3541 for the reason why this is important (hint:
GCC always predeclares these functions).
2) If users attempt to redeclare one of these library functions with
an incompatible signature, we produce a hard error.
This patch does a little bit of work to give reasonable error
messages. For example, when we hit case #1 we complain that we're
implicitly declaring this function with a specific signature, and then
we give a note that asks the user to include the appropriate header
(e.g., "please include <stdlib.h> or explicitly declare 'malloc'"). In
case #2, we show the type of the implicit builtin that was incorrectly
declared, so the user can see the problem. We could do better here:
for example, when displaying this latter error message we say
something like:
'strcpy' was implicitly declared here with type 'char *(char *, char
const *)'
but we should really print out a fake code line showing the
declaration, like this:
'strcpy' was implicitly declared here as:
char *strcpy(char *, char const *)
This would also be good for printing built-in candidates with C++
operator overloading.
The set of C library functions supported by this patch includes all
functions from the C99 specification's <stdlib.h> and <string.h> that
(a) are predefined by GCC and (b) have signatures that could cause
codegen issues if they are treated as functions with no prototype
returning and int. Future work could extend this set of functions to
other C library functions that we know about.
llvm-svn: 64504
2009-02-14 07:20:09 +08:00
|
|
|
/// \brief Returns a value indicating whether this function
|
|
|
|
/// corresponds to a builtin function.
|
|
|
|
///
|
|
|
|
/// The function corresponds to a built-in function if it is
|
|
|
|
/// declared at translation scope or within an extern "C" block and
|
|
|
|
/// its name matches with the name of a builtin. The returned value
|
|
|
|
/// will be 0 for functions that do not correspond to a builtin, a
|
2009-09-09 23:08:12 +08:00
|
|
|
/// value of type \c Builtin::ID if in the target-independent range
|
Implicitly declare certain C library functions (malloc, strcpy, memmove,
etc.) when we perform name lookup on them. This ensures that we
produce the correct signature for these functions, which has two
practical impacts:
1) When we're supporting the "implicit function declaration" feature
of C99, these functions will be implicitly declared with the right
signature rather than as a function returning "int" with no
prototype. See PR3541 for the reason why this is important (hint:
GCC always predeclares these functions).
2) If users attempt to redeclare one of these library functions with
an incompatible signature, we produce a hard error.
This patch does a little bit of work to give reasonable error
messages. For example, when we hit case #1 we complain that we're
implicitly declaring this function with a specific signature, and then
we give a note that asks the user to include the appropriate header
(e.g., "please include <stdlib.h> or explicitly declare 'malloc'"). In
case #2, we show the type of the implicit builtin that was incorrectly
declared, so the user can see the problem. We could do better here:
for example, when displaying this latter error message we say
something like:
'strcpy' was implicitly declared here with type 'char *(char *, char
const *)'
but we should really print out a fake code line showing the
declaration, like this:
'strcpy' was implicitly declared here as:
char *strcpy(char *, char const *)
This would also be good for printing built-in candidates with C++
operator overloading.
The set of C library functions supported by this patch includes all
functions from the C99 specification's <stdlib.h> and <string.h> that
(a) are predefined by GCC and (b) have signatures that could cause
codegen issues if they are treated as functions with no prototype
returning and int. Future work could extend this set of functions to
other C library functions that we know about.
llvm-svn: 64504
2009-02-14 07:20:09 +08:00
|
|
|
/// \c [1,Builtin::First), or a target-specific builtin value.
|
2009-09-12 08:22:50 +08:00
|
|
|
unsigned FunctionDecl::getBuiltinID() const {
|
2012-03-07 07:52:37 +08:00
|
|
|
if (!getIdentifier())
|
2009-02-15 02:57:46 +08:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
unsigned BuiltinID = getIdentifier()->getBuiltinID();
|
2012-03-07 07:52:37 +08:00
|
|
|
if (!BuiltinID)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
ASTContext &Context = getASTContext();
|
2013-11-02 07:46:51 +08:00
|
|
|
if (Context.getLangOpts().CPlusPlus) {
|
|
|
|
const LinkageSpecDecl *LinkageDecl = dyn_cast<LinkageSpecDecl>(
|
|
|
|
getFirstDecl()->getDeclContext());
|
|
|
|
// In C++, the first declaration of a builtin is always inside an implicit
|
|
|
|
// extern "C".
|
|
|
|
// FIXME: A recognised library function may not be directly in an extern "C"
|
|
|
|
// declaration, for instance "extern "C" { namespace std { decl } }".
|
2015-03-14 02:26:17 +08:00
|
|
|
if (!LinkageDecl) {
|
|
|
|
if (BuiltinID == Builtin::BI__GetExceptionInfo &&
|
|
|
|
Context.getTargetInfo().getCXXABI().isMicrosoft() &&
|
|
|
|
isInStdNamespace())
|
|
|
|
return Builtin::BI__GetExceptionInfo;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (LinkageDecl->getLanguage() != LinkageSpecDecl::lang_c)
|
2013-11-02 07:46:51 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the function is marked "overloadable", it has a different mangled name
|
|
|
|
// and is not the C library function.
|
2013-12-19 10:39:40 +08:00
|
|
|
if (hasAttr<OverloadableAttr>())
|
2013-11-02 07:46:51 +08:00
|
|
|
return 0;
|
|
|
|
|
2009-02-15 02:57:46 +08:00
|
|
|
if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
|
|
|
|
return BuiltinID;
|
|
|
|
|
|
|
|
// This function has the name of a known C library
|
|
|
|
// function. Determine whether it actually refers to the C library
|
|
|
|
// function or whether it just has the same name.
|
|
|
|
|
2009-02-17 11:23:10 +08:00
|
|
|
// If this is a static function, it's not a builtin.
|
2010-08-26 11:08:43 +08:00
|
|
|
if (getStorageClass() == SC_Static)
|
2009-02-17 11:23:10 +08:00
|
|
|
return 0;
|
|
|
|
|
2013-11-02 07:46:51 +08:00
|
|
|
return BuiltinID;
|
Implicitly declare certain C library functions (malloc, strcpy, memmove,
etc.) when we perform name lookup on them. This ensures that we
produce the correct signature for these functions, which has two
practical impacts:
1) When we're supporting the "implicit function declaration" feature
of C99, these functions will be implicitly declared with the right
signature rather than as a function returning "int" with no
prototype. See PR3541 for the reason why this is important (hint:
GCC always predeclares these functions).
2) If users attempt to redeclare one of these library functions with
an incompatible signature, we produce a hard error.
This patch does a little bit of work to give reasonable error
messages. For example, when we hit case #1 we complain that we're
implicitly declaring this function with a specific signature, and then
we give a note that asks the user to include the appropriate header
(e.g., "please include <stdlib.h> or explicitly declare 'malloc'"). In
case #2, we show the type of the implicit builtin that was incorrectly
declared, so the user can see the problem. We could do better here:
for example, when displaying this latter error message we say
something like:
'strcpy' was implicitly declared here with type 'char *(char *, char
const *)'
but we should really print out a fake code line showing the
declaration, like this:
'strcpy' was implicitly declared here as:
char *strcpy(char *, char const *)
This would also be good for printing built-in candidates with C++
operator overloading.
The set of C library functions supported by this patch includes all
functions from the C99 specification's <stdlib.h> and <string.h> that
(a) are predefined by GCC and (b) have signatures that could cause
codegen issues if they are treated as functions with no prototype
returning and int. Future work could extend this set of functions to
other C library functions that we know about.
llvm-svn: 64504
2009-02-14 07:20:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-25 14:03:53 +08:00
|
|
|
/// getNumParams - Return the number of parameters this function must have
|
2011-01-11 02:23:55 +08:00
|
|
|
/// based on its FunctionType. This is the length of the ParamInfo array
|
2009-04-25 14:03:53 +08:00
|
|
|
/// after it has been created.
|
|
|
|
unsigned FunctionDecl::getNumParams() const {
|
2013-12-05 09:23:43 +08:00
|
|
|
const FunctionProtoType *FPT = getType()->getAs<FunctionProtoType>();
|
2014-01-21 04:26:09 +08:00
|
|
|
return FPT ? FPT->getNumParams() : 0;
|
2007-01-21 15:42:07 +08:00
|
|
|
}
|
|
|
|
|
2010-09-09 03:31:22 +08:00
|
|
|
void FunctionDecl::setParams(ASTContext &C,
|
2013-01-13 03:30:44 +08:00
|
|
|
ArrayRef<ParmVarDecl *> NewParamInfo) {
|
2014-05-12 13:36:57 +08:00
|
|
|
assert(!ParamInfo && "Already has param info!");
|
2011-09-22 02:16:56 +08:00
|
|
|
assert(NewParamInfo.size() == getNumParams() && "Parameter count mismatch!");
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2007-01-22 03:04:10 +08:00
|
|
|
// Zero params -> null pointer.
|
2011-09-22 02:16:56 +08:00
|
|
|
if (!NewParamInfo.empty()) {
|
|
|
|
ParamInfo = new (C) ParmVarDecl*[NewParamInfo.size()];
|
|
|
|
std::copy(NewParamInfo.begin(), NewParamInfo.end(), ParamInfo);
|
2007-01-22 03:04:10 +08:00
|
|
|
}
|
2007-01-21 15:42:07 +08:00
|
|
|
}
|
2007-01-25 12:52:46 +08:00
|
|
|
|
2013-01-13 03:30:44 +08:00
|
|
|
void FunctionDecl::setDeclsInPrototypeScope(ArrayRef<NamedDecl *> NewDecls) {
|
2012-02-29 18:24:19 +08:00
|
|
|
assert(DeclsInPrototypeScope.empty() && "Already has prototype decls!");
|
|
|
|
|
|
|
|
if (!NewDecls.empty()) {
|
|
|
|
NamedDecl **A = new (getASTContext()) NamedDecl*[NewDecls.size()];
|
|
|
|
std::copy(NewDecls.begin(), NewDecls.end(), A);
|
2014-08-27 14:28:36 +08:00
|
|
|
DeclsInPrototypeScope = llvm::makeArrayRef(A, NewDecls.size());
|
2014-06-26 01:09:41 +08:00
|
|
|
// Move declarations introduced in prototype to the function context.
|
|
|
|
for (auto I : NewDecls) {
|
|
|
|
DeclContext *DC = I->getDeclContext();
|
|
|
|
// Forward-declared reference to an enumeration is not added to
|
|
|
|
// declaration scope, so skip declaration that is absent from its
|
|
|
|
// declaration contexts.
|
|
|
|
if (DC->containsDecl(I)) {
|
|
|
|
DC->removeDecl(I);
|
|
|
|
I->setDeclContext(this);
|
|
|
|
addDecl(I);
|
|
|
|
}
|
|
|
|
}
|
2012-02-29 18:24:19 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-04-10 10:22:51 +08:00
|
|
|
/// getMinRequiredArguments - Returns the minimum number of arguments
|
|
|
|
/// needed to call this function. This may be fewer than the number of
|
|
|
|
/// function parameters, if some of the parameters have default
|
2014-04-02 03:18:16 +08:00
|
|
|
/// arguments (in C++) or are parameter packs (C++11).
|
2008-04-10 10:22:51 +08:00
|
|
|
unsigned FunctionDecl::getMinRequiredArguments() const {
|
2012-03-11 15:00:24 +08:00
|
|
|
if (!getASTContext().getLangOpts().CPlusPlus)
|
2011-01-11 09:52:23 +08:00
|
|
|
return getNumParams();
|
2014-04-02 03:18:16 +08:00
|
|
|
|
|
|
|
unsigned NumRequiredArgs = 0;
|
|
|
|
for (auto *Param : params())
|
|
|
|
if (!Param->isParameterPack() && !Param->hasDefaultArg())
|
|
|
|
++NumRequiredArgs;
|
2008-04-10 10:22:51 +08:00
|
|
|
return NumRequiredArgs;
|
|
|
|
}
|
|
|
|
|
2014-04-03 07:17:29 +08:00
|
|
|
/// \brief The combination of the extern and inline keywords under MSVC forces
|
|
|
|
/// the function to be required.
|
|
|
|
///
|
|
|
|
/// Note: This function assumes that we will only get called when isInlined()
|
|
|
|
/// would return true for this FunctionDecl.
|
|
|
|
bool FunctionDecl::isMSExternInline() const {
|
|
|
|
assert(isInlined() && "expected to get called on an inlined function!");
|
|
|
|
|
|
|
|
const ASTContext &Context = getASTContext();
|
2014-05-16 06:07:49 +08:00
|
|
|
if (!Context.getLangOpts().MSVCCompat && !hasAttr<DLLExportAttr>())
|
2014-04-03 07:17:29 +08:00
|
|
|
return false;
|
|
|
|
|
2015-03-20 08:02:27 +08:00
|
|
|
for (const FunctionDecl *FD = getMostRecentDecl(); FD;
|
|
|
|
FD = FD->getPreviousDecl())
|
2014-04-03 07:17:29 +08:00
|
|
|
if (FD->getStorageClass() == SC_Extern)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool redeclForcesDefMSVC(const FunctionDecl *Redecl) {
|
|
|
|
if (Redecl->getStorageClass() != SC_Extern)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for (const FunctionDecl *FD = Redecl->getPreviousDecl(); FD;
|
|
|
|
FD = FD->getPreviousDecl())
|
|
|
|
if (FD->getStorageClass() == SC_Extern)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-02-07 11:50:18 +08:00
|
|
|
static bool RedeclForcesDefC99(const FunctionDecl *Redecl) {
|
|
|
|
// Only consider file-scope declarations in this test.
|
|
|
|
if (!Redecl->getLexicalDeclContext()->isTranslationUnit())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Only consider explicit declarations; the presence of a builtin for a
|
|
|
|
// libcall shouldn't affect whether a definition is externally visible.
|
|
|
|
if (Redecl->isImplicit())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!Redecl->isInlineSpecified() || Redecl->getStorageClass() == SC_Extern)
|
|
|
|
return true; // Not an inline definition
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-07-18 13:26:13 +08:00
|
|
|
/// \brief For a function declaration in C or C++, determine whether this
|
|
|
|
/// declaration causes the definition to be externally visible.
|
|
|
|
///
|
2014-04-03 07:17:29 +08:00
|
|
|
/// For instance, this determines if adding the current declaration to the set
|
2012-02-07 11:50:18 +08:00
|
|
|
/// of redeclarations of the given functions causes
|
|
|
|
/// isInlineDefinitionExternallyVisible to change from false to true.
|
2011-07-18 13:26:13 +08:00
|
|
|
bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const {
|
|
|
|
assert(!doesThisDeclarationHaveABody() &&
|
|
|
|
"Must have a declaration without a body.");
|
|
|
|
|
|
|
|
ASTContext &Context = getASTContext();
|
|
|
|
|
2014-04-03 07:17:29 +08:00
|
|
|
if (Context.getLangOpts().MSVCCompat) {
|
|
|
|
const FunctionDecl *Definition;
|
|
|
|
if (hasBody(Definition) && Definition->isInlined() &&
|
|
|
|
redeclForcesDefMSVC(this))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-03-11 15:00:24 +08:00
|
|
|
if (Context.getLangOpts().GNUInline || hasAttr<GNUInlineAttr>()) {
|
2012-02-07 11:50:18 +08:00
|
|
|
// With GNU inlining, a declaration with 'inline' but not 'extern', forces
|
|
|
|
// an externally visible definition.
|
|
|
|
//
|
|
|
|
// FIXME: What happens if gnu_inline gets added on after the first
|
|
|
|
// declaration?
|
2013-04-04 03:27:57 +08:00
|
|
|
if (!isInlineSpecified() || getStorageClass() == SC_Extern)
|
2012-02-07 11:50:18 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
const FunctionDecl *Prev = this;
|
|
|
|
bool FoundBody = false;
|
|
|
|
while ((Prev = Prev->getPreviousDecl())) {
|
2013-05-15 15:37:26 +08:00
|
|
|
FoundBody |= Prev->Body.isValid();
|
2012-02-07 11:50:18 +08:00
|
|
|
|
|
|
|
if (Prev->Body) {
|
|
|
|
// If it's not the case that both 'inline' and 'extern' are
|
|
|
|
// specified on the definition, then it is always externally visible.
|
|
|
|
if (!Prev->isInlineSpecified() ||
|
2013-04-04 03:27:57 +08:00
|
|
|
Prev->getStorageClass() != SC_Extern)
|
2012-02-07 11:50:18 +08:00
|
|
|
return false;
|
|
|
|
} else if (Prev->isInlineSpecified() &&
|
2013-04-04 03:27:57 +08:00
|
|
|
Prev->getStorageClass() != SC_Extern) {
|
2012-02-07 11:50:18 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return FoundBody;
|
|
|
|
}
|
|
|
|
|
2012-03-11 15:00:24 +08:00
|
|
|
if (Context.getLangOpts().CPlusPlus)
|
2011-07-18 13:26:13 +08:00
|
|
|
return false;
|
2012-02-07 11:50:18 +08:00
|
|
|
|
|
|
|
// C99 6.7.4p6:
|
|
|
|
// [...] If all of the file scope declarations for a function in a
|
|
|
|
// translation unit include the inline function specifier without extern,
|
|
|
|
// then the definition in that translation unit is an inline definition.
|
|
|
|
if (isInlineSpecified() && getStorageClass() != SC_Extern)
|
2011-07-18 13:26:13 +08:00
|
|
|
return false;
|
2012-02-07 11:50:18 +08:00
|
|
|
const FunctionDecl *Prev = this;
|
|
|
|
bool FoundBody = false;
|
|
|
|
while ((Prev = Prev->getPreviousDecl())) {
|
2013-05-15 15:37:26 +08:00
|
|
|
FoundBody |= Prev->Body.isValid();
|
2012-02-07 11:50:18 +08:00
|
|
|
if (RedeclForcesDefC99(Prev))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return FoundBody;
|
2011-07-18 13:26:13 +08:00
|
|
|
}
|
|
|
|
|
2014-07-02 09:47:15 +08:00
|
|
|
SourceRange FunctionDecl::getReturnTypeSourceRange() const {
|
|
|
|
const TypeSourceInfo *TSI = getTypeSourceInfo();
|
|
|
|
if (!TSI)
|
|
|
|
return SourceRange();
|
2014-07-02 20:55:58 +08:00
|
|
|
FunctionTypeLoc FTL =
|
|
|
|
TSI->getTypeLoc().IgnoreParens().getAs<FunctionTypeLoc>();
|
|
|
|
if (!FTL)
|
2014-07-02 09:47:15 +08:00
|
|
|
return SourceRange();
|
|
|
|
|
2014-07-02 20:55:58 +08:00
|
|
|
// Skip self-referential return types.
|
|
|
|
const SourceManager &SM = getASTContext().getSourceManager();
|
|
|
|
SourceRange RTRange = FTL.getReturnLoc().getSourceRange();
|
|
|
|
SourceLocation Boundary = getNameInfo().getLocStart();
|
|
|
|
if (RTRange.isInvalid() || Boundary.isInvalid() ||
|
|
|
|
!SM.isBeforeInTranslationUnit(RTRange.getEnd(), Boundary))
|
|
|
|
return SourceRange();
|
2014-07-02 09:47:15 +08:00
|
|
|
|
2014-07-02 20:55:58 +08:00
|
|
|
return RTRange;
|
2014-07-02 09:47:15 +08:00
|
|
|
}
|
|
|
|
|
2015-04-10 03:43:04 +08:00
|
|
|
bool FunctionDecl::hasUnusedResultAttr() const {
|
|
|
|
QualType RetType = getReturnType();
|
|
|
|
if (RetType->isRecordType()) {
|
|
|
|
const CXXRecordDecl *Ret = RetType->getAsCXXRecordDecl();
|
|
|
|
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(this);
|
|
|
|
if (Ret && Ret->hasAttr<WarnUnusedResultAttr>() &&
|
|
|
|
!(MD && MD->getCorrespondingMethodInClass(Ret, true)))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return hasAttr<WarnUnusedResultAttr>();
|
|
|
|
}
|
|
|
|
|
2013-01-25 08:08:28 +08:00
|
|
|
/// \brief For an inline function definition in C, or for a gnu_inline function
|
|
|
|
/// in C++, determine whether the definition will be externally visible.
|
2009-09-13 15:46:26 +08:00
|
|
|
///
|
|
|
|
/// Inline function definitions are always available for inlining optimizations.
|
|
|
|
/// However, depending on the language dialect, declaration specifiers, and
|
|
|
|
/// attributes, the definition of an inline function may or may not be
|
|
|
|
/// "externally" visible to other translation units in the program.
|
|
|
|
///
|
|
|
|
/// In C99, inline definitions are not externally visible by default. However,
|
2010-01-06 10:05:39 +08:00
|
|
|
/// if even one of the global-scope declarations is marked "extern inline", the
|
2009-09-13 15:46:26 +08:00
|
|
|
/// inline definition becomes externally visible (C99 6.7.4p6).
|
|
|
|
///
|
|
|
|
/// In GNU89 mode, or if the gnu_inline attribute is attached to the function
|
|
|
|
/// definition, we use the GNU semantics for inline, which are nearly the
|
|
|
|
/// opposite of C99 semantics. In particular, "inline" by itself will create
|
|
|
|
/// an externally visible symbol, but "extern inline" will not create an
|
|
|
|
/// externally visible symbol.
|
|
|
|
bool FunctionDecl::isInlineDefinitionExternallyVisible() const {
|
2011-05-07 04:44:56 +08:00
|
|
|
assert(doesThisDeclarationHaveABody() && "Must have the function definition");
|
2009-10-28 05:11:48 +08:00
|
|
|
assert(isInlined() && "Function must be inline");
|
2009-10-28 07:26:40 +08:00
|
|
|
ASTContext &Context = getASTContext();
|
2009-09-13 15:46:26 +08:00
|
|
|
|
2012-03-11 15:00:24 +08:00
|
|
|
if (Context.getLangOpts().GNUInline || hasAttr<GNUInlineAttr>()) {
|
2012-02-07 11:50:18 +08:00
|
|
|
// Note: If you change the logic here, please change
|
|
|
|
// doesDeclarationForceExternallyVisibleDefinition as well.
|
|
|
|
//
|
2010-12-10 00:59:22 +08:00
|
|
|
// If it's not the case that both 'inline' and 'extern' are
|
|
|
|
// specified on the definition, then this inline definition is
|
|
|
|
// externally visible.
|
2013-04-04 03:27:57 +08:00
|
|
|
if (!(isInlineSpecified() && getStorageClass() == SC_Extern))
|
2010-12-10 00:59:22 +08:00
|
|
|
return true;
|
|
|
|
|
|
|
|
// If any declaration is 'inline' but not 'extern', then this definition
|
|
|
|
// is externally visible.
|
2014-03-07 07:45:36 +08:00
|
|
|
for (auto Redecl : redecls()) {
|
2010-12-10 00:59:22 +08:00
|
|
|
if (Redecl->isInlineSpecified() &&
|
2013-04-04 03:27:57 +08:00
|
|
|
Redecl->getStorageClass() != SC_Extern)
|
2009-09-13 15:46:26 +08:00
|
|
|
return true;
|
2010-12-10 00:59:22 +08:00
|
|
|
}
|
2009-09-13 15:46:26 +08:00
|
|
|
|
2009-04-28 14:37:30 +08:00
|
|
|
return false;
|
2009-09-13 15:46:26 +08:00
|
|
|
}
|
2012-02-07 11:50:18 +08:00
|
|
|
|
2013-01-25 08:08:28 +08:00
|
|
|
// The rest of this function is C-only.
|
|
|
|
assert(!Context.getLangOpts().CPlusPlus &&
|
|
|
|
"should not use C inline rules in C++");
|
|
|
|
|
2009-09-13 15:46:26 +08:00
|
|
|
// C99 6.7.4p6:
|
|
|
|
// [...] If all of the file scope declarations for a function in a
|
|
|
|
// translation unit include the inline function specifier without extern,
|
|
|
|
// then the definition in that translation unit is an inline definition.
|
2014-03-07 07:45:36 +08:00
|
|
|
for (auto Redecl : redecls()) {
|
|
|
|
if (RedeclForcesDefC99(Redecl))
|
2012-02-07 11:50:18 +08:00
|
|
|
return true;
|
2009-09-13 15:46:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// C99 6.7.4p6:
|
|
|
|
// An inline definition does not provide an external definition for the
|
|
|
|
// function, and does not forbid an external definition in another
|
|
|
|
// translation unit.
|
2009-04-28 14:37:30 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2008-11-07 06:13:31 +08:00
|
|
|
/// getOverloadedOperator - Which C++ overloaded operator this
|
|
|
|
/// function represents, if any.
|
|
|
|
OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const {
|
Extend DeclarationName to support C++ overloaded operators, e.g.,
operator+, directly, using the same mechanism as all other special
names.
Removed the "special" identifiers for the overloaded operators from
the identifier table and IdentifierInfo data structure. IdentifierInfo
is back to representing only real identifiers.
Added a new Action, ActOnOperatorFunctionIdExpr, that builds an
expression from an parsed operator-function-id (e.g., "operator
+"). ActOnIdentifierExpr used to do this job, but
operator-function-ids are no longer represented by IdentifierInfo's.
Extended Declarator to store overloaded operator names.
Sema::GetNameForDeclarator now knows how to turn the operator
name into a DeclarationName for the overloaded operator.
Except for (perhaps) consolidating the functionality of
ActOnIdentifier, ActOnOperatorFunctionIdExpr, and
ActOnConversionFunctionExpr into a common routine that builds an
appropriate DeclRefExpr by looking up a DeclarationName, all of the
work on normalizing declaration names should be complete with this
commit.
llvm-svn: 59526
2008-11-18 22:39:36 +08:00
|
|
|
if (getDeclName().getNameKind() == DeclarationName::CXXOperatorName)
|
|
|
|
return getDeclName().getCXXOverloadedOperator();
|
2008-11-07 06:13:31 +08:00
|
|
|
else
|
|
|
|
return OO_None;
|
|
|
|
}
|
|
|
|
|
2010-01-13 17:01:02 +08:00
|
|
|
/// getLiteralIdentifier - The literal suffix identifier this function
|
|
|
|
/// represents, if any.
|
|
|
|
const IdentifierInfo *FunctionDecl::getLiteralIdentifier() const {
|
|
|
|
if (getDeclName().getNameKind() == DeclarationName::CXXLiteralOperatorName)
|
|
|
|
return getDeclName().getCXXLiteralIdentifier();
|
|
|
|
else
|
2014-05-12 13:36:57 +08:00
|
|
|
return nullptr;
|
2010-01-13 17:01:02 +08:00
|
|
|
}
|
|
|
|
|
2010-06-22 17:54:51 +08:00
|
|
|
FunctionDecl::TemplatedKind FunctionDecl::getTemplatedKind() const {
|
|
|
|
if (TemplateOrSpecialization.isNull())
|
|
|
|
return TK_NonTemplate;
|
|
|
|
if (TemplateOrSpecialization.is<FunctionTemplateDecl *>())
|
|
|
|
return TK_FunctionTemplate;
|
|
|
|
if (TemplateOrSpecialization.is<MemberSpecializationInfo *>())
|
|
|
|
return TK_MemberSpecialization;
|
|
|
|
if (TemplateOrSpecialization.is<FunctionTemplateSpecializationInfo *>())
|
|
|
|
return TK_FunctionTemplateSpecialization;
|
|
|
|
if (TemplateOrSpecialization.is
|
|
|
|
<DependentFunctionTemplateSpecializationInfo*>())
|
|
|
|
return TK_DependentFunctionTemplateSpecialization;
|
|
|
|
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable("Did we miss a TemplateOrSpecialization type?");
|
2010-06-22 17:54:51 +08:00
|
|
|
}
|
|
|
|
|
2009-10-08 07:56:10 +08:00
|
|
|
FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const {
|
2009-10-13 04:18:28 +08:00
|
|
|
if (MemberSpecializationInfo *Info = getMemberSpecializationInfo())
|
2009-10-08 07:56:10 +08:00
|
|
|
return cast<FunctionDecl>(Info->getInstantiatedFrom());
|
2014-05-12 13:36:57 +08:00
|
|
|
|
|
|
|
return nullptr;
|
2009-10-08 07:56:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-09-09 03:31:22 +08:00
|
|
|
FunctionDecl::setInstantiationOfMemberFunction(ASTContext &C,
|
|
|
|
FunctionDecl *FD,
|
2009-10-08 07:56:10 +08:00
|
|
|
TemplateSpecializationKind TSK) {
|
|
|
|
assert(TemplateOrSpecialization.isNull() &&
|
|
|
|
"Member function is already a specialization");
|
|
|
|
MemberSpecializationInfo *Info
|
2010-09-09 03:31:22 +08:00
|
|
|
= new (C) MemberSpecializationInfo(FD, TSK);
|
2009-10-08 07:56:10 +08:00
|
|
|
TemplateOrSpecialization = Info;
|
|
|
|
}
|
|
|
|
|
2009-10-28 04:53:28 +08:00
|
|
|
bool FunctionDecl::isImplicitlyInstantiable() const {
|
2010-05-18 01:34:56 +08:00
|
|
|
// If the function is invalid, it can't be implicitly instantiated.
|
|
|
|
if (isInvalidDecl())
|
2009-10-28 04:53:28 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
switch (getTemplateSpecializationKind()) {
|
|
|
|
case TSK_Undeclared:
|
|
|
|
case TSK_ExplicitInstantiationDefinition:
|
|
|
|
return false;
|
|
|
|
|
|
|
|
case TSK_ImplicitInstantiation:
|
|
|
|
return true;
|
|
|
|
|
2011-08-14 11:52:19 +08:00
|
|
|
// It is possible to instantiate TSK_ExplicitSpecialization kind
|
|
|
|
// if the FunctionDecl has a class scope specialization pattern.
|
|
|
|
case TSK_ExplicitSpecialization:
|
2014-05-12 13:36:57 +08:00
|
|
|
return getClassScopeSpecializationPattern() != nullptr;
|
2011-08-14 11:52:19 +08:00
|
|
|
|
2009-10-28 04:53:28 +08:00
|
|
|
case TSK_ExplicitInstantiationDeclaration:
|
|
|
|
// Handled below.
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Find the actual template from which we will instantiate.
|
|
|
|
const FunctionDecl *PatternDecl = getTemplateInstantiationPattern();
|
2010-07-07 19:31:19 +08:00
|
|
|
bool HasPattern = false;
|
2009-10-28 04:53:28 +08:00
|
|
|
if (PatternDecl)
|
2010-07-07 19:31:19 +08:00
|
|
|
HasPattern = PatternDecl->hasBody(PatternDecl);
|
2009-10-28 04:53:28 +08:00
|
|
|
|
|
|
|
// C++0x [temp.explicit]p9:
|
|
|
|
// Except for inline functions, other explicit instantiation declarations
|
|
|
|
// have the effect of suppressing the implicit instantiation of the entity
|
|
|
|
// to which they refer.
|
2010-07-07 19:31:19 +08:00
|
|
|
if (!HasPattern || !PatternDecl)
|
2009-10-28 04:53:28 +08:00
|
|
|
return true;
|
|
|
|
|
2009-10-28 05:11:48 +08:00
|
|
|
return PatternDecl->isInlined();
|
2011-12-01 08:59:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool FunctionDecl::isTemplateInstantiation() const {
|
|
|
|
switch (getTemplateSpecializationKind()) {
|
|
|
|
case TSK_Undeclared:
|
|
|
|
case TSK_ExplicitSpecialization:
|
|
|
|
return false;
|
|
|
|
case TSK_ImplicitInstantiation:
|
|
|
|
case TSK_ExplicitInstantiationDeclaration:
|
|
|
|
case TSK_ExplicitInstantiationDefinition:
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
llvm_unreachable("All TSK values handled.");
|
|
|
|
}
|
2009-10-28 04:53:28 +08:00
|
|
|
|
|
|
|
FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const {
|
2011-08-14 11:52:19 +08:00
|
|
|
// Handle class scope explicit specialization special case.
|
|
|
|
if (getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
|
|
|
|
return getClassScopeSpecializationPattern();
|
2014-04-04 00:32:21 +08:00
|
|
|
|
|
|
|
// If this is a generic lambda call operator specialization, its
|
|
|
|
// instantiation pattern is always its primary template's pattern
|
|
|
|
// even if its primary template was instantiated from another
|
|
|
|
// member template (which happens with nested generic lambdas).
|
|
|
|
// Since a lambda's call operator's body is transformed eagerly,
|
|
|
|
// we don't have to go hunting for a prototype definition template
|
|
|
|
// (i.e. instantiated-from-member-template) to use as an instantiation
|
|
|
|
// pattern.
|
|
|
|
|
|
|
|
if (isGenericLambdaCallOperatorSpecialization(
|
|
|
|
dyn_cast<CXXMethodDecl>(this))) {
|
|
|
|
assert(getPrimaryTemplate() && "A generic lambda specialization must be "
|
|
|
|
"generated from a primary call operator "
|
|
|
|
"template");
|
|
|
|
assert(getPrimaryTemplate()->getTemplatedDecl()->getBody() &&
|
|
|
|
"A generic lambda call operator template must always have a body - "
|
|
|
|
"even if instantiated from a prototype (i.e. as written) member "
|
|
|
|
"template");
|
|
|
|
return getPrimaryTemplate()->getTemplatedDecl();
|
|
|
|
}
|
|
|
|
|
2009-10-28 04:53:28 +08:00
|
|
|
if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) {
|
|
|
|
while (Primary->getInstantiatedFromMemberTemplate()) {
|
|
|
|
// If we have hit a point where the user provided a specialization of
|
|
|
|
// this template, we're done looking.
|
|
|
|
if (Primary->isMemberSpecialization())
|
|
|
|
break;
|
|
|
|
Primary = Primary->getInstantiatedFromMemberTemplate();
|
|
|
|
}
|
|
|
|
|
|
|
|
return Primary->getTemplatedDecl();
|
|
|
|
}
|
|
|
|
|
|
|
|
return getInstantiatedFromMemberFunction();
|
|
|
|
}
|
|
|
|
|
2009-06-30 01:30:29 +08:00
|
|
|
FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const {
|
2009-09-09 23:08:12 +08:00
|
|
|
if (FunctionTemplateSpecializationInfo *Info
|
2009-06-30 01:30:29 +08:00
|
|
|
= TemplateOrSpecialization
|
|
|
|
.dyn_cast<FunctionTemplateSpecializationInfo*>()) {
|
2009-06-30 06:39:32 +08:00
|
|
|
return Info->Template.getPointer();
|
2009-06-30 01:30:29 +08:00
|
|
|
}
|
2014-05-12 13:36:57 +08:00
|
|
|
return nullptr;
|
2009-06-30 01:30:29 +08:00
|
|
|
}
|
|
|
|
|
2011-08-14 11:52:19 +08:00
|
|
|
FunctionDecl *FunctionDecl::getClassScopeSpecializationPattern() const {
|
|
|
|
return getASTContext().getClassScopeSpecializationPattern(this);
|
|
|
|
}
|
|
|
|
|
2009-06-30 01:30:29 +08:00
|
|
|
const TemplateArgumentList *
|
|
|
|
FunctionDecl::getTemplateSpecializationArgs() const {
|
2009-09-09 23:08:12 +08:00
|
|
|
if (FunctionTemplateSpecializationInfo *Info
|
2009-10-14 00:30:37 +08:00
|
|
|
= TemplateOrSpecialization
|
|
|
|
.dyn_cast<FunctionTemplateSpecializationInfo*>()) {
|
2009-06-30 01:30:29 +08:00
|
|
|
return Info->TemplateArguments;
|
|
|
|
}
|
2014-05-12 13:36:57 +08:00
|
|
|
return nullptr;
|
2009-06-30 01:30:29 +08:00
|
|
|
}
|
|
|
|
|
2011-09-23 04:07:09 +08:00
|
|
|
const ASTTemplateArgumentListInfo *
|
2010-05-20 23:32:11 +08:00
|
|
|
FunctionDecl::getTemplateSpecializationArgsAsWritten() const {
|
|
|
|
if (FunctionTemplateSpecializationInfo *Info
|
|
|
|
= TemplateOrSpecialization
|
|
|
|
.dyn_cast<FunctionTemplateSpecializationInfo*>()) {
|
|
|
|
return Info->TemplateArgumentsAsWritten;
|
|
|
|
}
|
2014-05-12 13:36:57 +08:00
|
|
|
return nullptr;
|
2010-05-20 23:32:11 +08:00
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
void
|
2010-09-09 03:31:22 +08:00
|
|
|
FunctionDecl::setFunctionTemplateSpecialization(ASTContext &C,
|
|
|
|
FunctionTemplateDecl *Template,
|
2009-06-30 04:59:39 +08:00
|
|
|
const TemplateArgumentList *TemplateArgs,
|
2009-09-25 07:14:47 +08:00
|
|
|
void *InsertPos,
|
2010-05-20 23:32:11 +08:00
|
|
|
TemplateSpecializationKind TSK,
|
2010-07-05 18:37:55 +08:00
|
|
|
const TemplateArgumentListInfo *TemplateArgsAsWritten,
|
|
|
|
SourceLocation PointOfInstantiation) {
|
2009-09-25 07:14:47 +08:00
|
|
|
assert(TSK != TSK_Undeclared &&
|
|
|
|
"Must specify the type of function template specialization");
|
2009-09-09 23:08:12 +08:00
|
|
|
FunctionTemplateSpecializationInfo *Info
|
2009-06-30 01:30:29 +08:00
|
|
|
= TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
|
2009-06-26 08:10:03 +08:00
|
|
|
if (!Info)
|
2010-09-09 19:28:23 +08:00
|
|
|
Info = FunctionTemplateSpecializationInfo::Create(C, this, Template, TSK,
|
|
|
|
TemplateArgs,
|
|
|
|
TemplateArgsAsWritten,
|
|
|
|
PointOfInstantiation);
|
2009-06-26 08:10:03 +08:00
|
|
|
TemplateOrSpecialization = Info;
|
2012-03-28 22:34:23 +08:00
|
|
|
Template->addSpecialization(Info, InsertPos);
|
2009-06-26 08:10:03 +08:00
|
|
|
}
|
|
|
|
|
2010-04-08 17:05:18 +08:00
|
|
|
void
|
|
|
|
FunctionDecl::setDependentTemplateSpecialization(ASTContext &Context,
|
|
|
|
const UnresolvedSetImpl &Templates,
|
|
|
|
const TemplateArgumentListInfo &TemplateArgs) {
|
|
|
|
assert(TemplateOrSpecialization.isNull());
|
|
|
|
size_t Size = sizeof(DependentFunctionTemplateSpecializationInfo);
|
|
|
|
Size += Templates.size() * sizeof(FunctionTemplateDecl*);
|
2010-04-14 06:18:28 +08:00
|
|
|
Size += TemplateArgs.size() * sizeof(TemplateArgumentLoc);
|
2010-04-08 17:05:18 +08:00
|
|
|
void *Buffer = Context.Allocate(Size);
|
|
|
|
DependentFunctionTemplateSpecializationInfo *Info =
|
|
|
|
new (Buffer) DependentFunctionTemplateSpecializationInfo(Templates,
|
|
|
|
TemplateArgs);
|
|
|
|
TemplateOrSpecialization = Info;
|
|
|
|
}
|
|
|
|
|
|
|
|
DependentFunctionTemplateSpecializationInfo::
|
|
|
|
DependentFunctionTemplateSpecializationInfo(const UnresolvedSetImpl &Ts,
|
|
|
|
const TemplateArgumentListInfo &TArgs)
|
2015-04-02 20:43:31 +08:00
|
|
|
: AngleLocs(TArgs.getLAngleLoc(), TArgs.getRAngleLoc()) {
|
2015-04-02 20:25:07 +08:00
|
|
|
static_assert(sizeof(*this) % llvm::AlignOf<void *>::Alignment == 0,
|
|
|
|
"Trailing data is unaligned!");
|
2010-04-08 17:05:18 +08:00
|
|
|
|
2015-04-02 20:43:31 +08:00
|
|
|
d.NumTemplates = Ts.size();
|
|
|
|
d.NumArgs = TArgs.size();
|
|
|
|
|
2010-04-08 17:05:18 +08:00
|
|
|
FunctionTemplateDecl **TsArray =
|
|
|
|
const_cast<FunctionTemplateDecl**>(getTemplates());
|
|
|
|
for (unsigned I = 0, E = Ts.size(); I != E; ++I)
|
|
|
|
TsArray[I] = cast<FunctionTemplateDecl>(Ts[I]->getUnderlyingDecl());
|
|
|
|
|
|
|
|
TemplateArgumentLoc *ArgsArray =
|
|
|
|
const_cast<TemplateArgumentLoc*>(getTemplateArgs());
|
|
|
|
for (unsigned I = 0, E = TArgs.size(); I != E; ++I)
|
|
|
|
new (&ArgsArray[I]) TemplateArgumentLoc(TArgs[I]);
|
|
|
|
}
|
|
|
|
|
2009-09-05 06:48:11 +08:00
|
|
|
TemplateSpecializationKind FunctionDecl::getTemplateSpecializationKind() const {
|
2009-09-09 23:08:12 +08:00
|
|
|
// For a function template specialization, query the specialization
|
2009-09-05 06:48:11 +08:00
|
|
|
// information object.
|
2009-10-08 07:56:10 +08:00
|
|
|
FunctionTemplateSpecializationInfo *FTSInfo
|
2009-06-30 06:39:32 +08:00
|
|
|
= TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
|
2009-10-08 07:56:10 +08:00
|
|
|
if (FTSInfo)
|
|
|
|
return FTSInfo->getTemplateSpecializationKind();
|
2009-09-05 06:48:11 +08:00
|
|
|
|
2009-10-08 07:56:10 +08:00
|
|
|
MemberSpecializationInfo *MSInfo
|
|
|
|
= TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>();
|
|
|
|
if (MSInfo)
|
|
|
|
return MSInfo->getTemplateSpecializationKind();
|
|
|
|
|
|
|
|
return TSK_Undeclared;
|
2009-06-30 06:39:32 +08:00
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
void
|
2009-10-16 01:21:20 +08:00
|
|
|
FunctionDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
|
|
|
|
SourceLocation PointOfInstantiation) {
|
2009-10-08 07:56:10 +08:00
|
|
|
if (FunctionTemplateSpecializationInfo *FTSInfo
|
|
|
|
= TemplateOrSpecialization.dyn_cast<
|
2009-10-16 01:21:20 +08:00
|
|
|
FunctionTemplateSpecializationInfo*>()) {
|
2009-10-08 07:56:10 +08:00
|
|
|
FTSInfo->setTemplateSpecializationKind(TSK);
|
2009-10-16 01:21:20 +08:00
|
|
|
if (TSK != TSK_ExplicitSpecialization &&
|
|
|
|
PointOfInstantiation.isValid() &&
|
|
|
|
FTSInfo->getPointOfInstantiation().isInvalid())
|
|
|
|
FTSInfo->setPointOfInstantiation(PointOfInstantiation);
|
|
|
|
} else if (MemberSpecializationInfo *MSInfo
|
|
|
|
= TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>()) {
|
2009-10-08 07:56:10 +08:00
|
|
|
MSInfo->setTemplateSpecializationKind(TSK);
|
2009-10-16 01:21:20 +08:00
|
|
|
if (TSK != TSK_ExplicitSpecialization &&
|
|
|
|
PointOfInstantiation.isValid() &&
|
|
|
|
MSInfo->getPointOfInstantiation().isInvalid())
|
|
|
|
MSInfo->setPointOfInstantiation(PointOfInstantiation);
|
|
|
|
} else
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable("Function cannot have a template specialization kind");
|
2009-06-30 06:39:32 +08:00
|
|
|
}
|
|
|
|
|
2009-10-16 01:21:20 +08:00
|
|
|
SourceLocation FunctionDecl::getPointOfInstantiation() const {
|
|
|
|
if (FunctionTemplateSpecializationInfo *FTSInfo
|
|
|
|
= TemplateOrSpecialization.dyn_cast<
|
|
|
|
FunctionTemplateSpecializationInfo*>())
|
|
|
|
return FTSInfo->getPointOfInstantiation();
|
|
|
|
else if (MemberSpecializationInfo *MSInfo
|
|
|
|
= TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>())
|
|
|
|
return MSInfo->getPointOfInstantiation();
|
|
|
|
|
|
|
|
return SourceLocation();
|
|
|
|
}
|
|
|
|
|
2009-09-12 04:15:17 +08:00
|
|
|
bool FunctionDecl::isOutOfLine() const {
|
2011-02-20 02:51:44 +08:00
|
|
|
if (Decl::isOutOfLine())
|
2009-09-12 04:15:17 +08:00
|
|
|
return true;
|
|
|
|
|
|
|
|
// If this function was instantiated from a member function of a
|
|
|
|
// class template, check whether that member function was defined out-of-line.
|
|
|
|
if (FunctionDecl *FD = getInstantiatedFromMemberFunction()) {
|
|
|
|
const FunctionDecl *Definition;
|
2010-07-07 19:31:19 +08:00
|
|
|
if (FD->hasBody(Definition))
|
2009-09-12 04:15:17 +08:00
|
|
|
return Definition->isOutOfLine();
|
|
|
|
}
|
|
|
|
|
|
|
|
// If this function was instantiated from a function template,
|
|
|
|
// check whether that function template was defined out-of-line.
|
|
|
|
if (FunctionTemplateDecl *FunTmpl = getPrimaryTemplate()) {
|
|
|
|
const FunctionDecl *Definition;
|
2010-07-07 19:31:19 +08:00
|
|
|
if (FunTmpl->getTemplatedDecl()->hasBody(Definition))
|
2009-09-12 04:15:17 +08:00
|
|
|
return Definition->isOutOfLine();
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-03-09 00:41:52 +08:00
|
|
|
SourceRange FunctionDecl::getSourceRange() const {
|
|
|
|
return SourceRange(getOuterLocStart(), EndRangeLoc);
|
|
|
|
}
|
|
|
|
|
2012-01-18 10:45:01 +08:00
|
|
|
unsigned FunctionDecl::getMemoryFunctionKind() const {
|
2012-01-14 05:52:01 +08:00
|
|
|
IdentifierInfo *FnInfo = getIdentifier();
|
|
|
|
|
|
|
|
if (!FnInfo)
|
2012-01-17 08:37:07 +08:00
|
|
|
return 0;
|
2012-01-14 05:52:01 +08:00
|
|
|
|
|
|
|
// Builtin handling.
|
|
|
|
switch (getBuiltinID()) {
|
|
|
|
case Builtin::BI__builtin_memset:
|
|
|
|
case Builtin::BI__builtin___memset_chk:
|
|
|
|
case Builtin::BImemset:
|
2012-01-17 08:37:07 +08:00
|
|
|
return Builtin::BImemset;
|
2012-01-14 05:52:01 +08:00
|
|
|
|
|
|
|
case Builtin::BI__builtin_memcpy:
|
|
|
|
case Builtin::BI__builtin___memcpy_chk:
|
|
|
|
case Builtin::BImemcpy:
|
2012-01-17 08:37:07 +08:00
|
|
|
return Builtin::BImemcpy;
|
2012-01-14 05:52:01 +08:00
|
|
|
|
|
|
|
case Builtin::BI__builtin_memmove:
|
|
|
|
case Builtin::BI__builtin___memmove_chk:
|
|
|
|
case Builtin::BImemmove:
|
2012-01-17 08:37:07 +08:00
|
|
|
return Builtin::BImemmove;
|
2012-01-14 05:52:01 +08:00
|
|
|
|
|
|
|
case Builtin::BIstrlcpy:
|
2014-09-13 02:44:36 +08:00
|
|
|
case Builtin::BI__builtin___strlcpy_chk:
|
2012-01-17 08:37:07 +08:00
|
|
|
return Builtin::BIstrlcpy;
|
2014-09-13 02:44:36 +08:00
|
|
|
|
2012-01-14 05:52:01 +08:00
|
|
|
case Builtin::BIstrlcat:
|
2014-09-13 02:44:36 +08:00
|
|
|
case Builtin::BI__builtin___strlcat_chk:
|
2012-01-17 08:37:07 +08:00
|
|
|
return Builtin::BIstrlcat;
|
2012-01-14 05:52:01 +08:00
|
|
|
|
|
|
|
case Builtin::BI__builtin_memcmp:
|
2012-01-17 08:37:07 +08:00
|
|
|
case Builtin::BImemcmp:
|
|
|
|
return Builtin::BImemcmp;
|
2012-01-14 05:52:01 +08:00
|
|
|
|
|
|
|
case Builtin::BI__builtin_strncpy:
|
|
|
|
case Builtin::BI__builtin___strncpy_chk:
|
|
|
|
case Builtin::BIstrncpy:
|
2012-01-17 08:37:07 +08:00
|
|
|
return Builtin::BIstrncpy;
|
2012-01-14 05:52:01 +08:00
|
|
|
|
|
|
|
case Builtin::BI__builtin_strncmp:
|
2012-01-17 08:37:07 +08:00
|
|
|
case Builtin::BIstrncmp:
|
|
|
|
return Builtin::BIstrncmp;
|
2012-01-14 05:52:01 +08:00
|
|
|
|
|
|
|
case Builtin::BI__builtin_strncasecmp:
|
2012-01-17 08:37:07 +08:00
|
|
|
case Builtin::BIstrncasecmp:
|
|
|
|
return Builtin::BIstrncasecmp;
|
2012-01-14 05:52:01 +08:00
|
|
|
|
|
|
|
case Builtin::BI__builtin_strncat:
|
2012-02-02 03:08:57 +08:00
|
|
|
case Builtin::BI__builtin___strncat_chk:
|
2012-01-14 05:52:01 +08:00
|
|
|
case Builtin::BIstrncat:
|
2012-01-17 08:37:07 +08:00
|
|
|
return Builtin::BIstrncat;
|
2012-01-14 05:52:01 +08:00
|
|
|
|
|
|
|
case Builtin::BI__builtin_strndup:
|
|
|
|
case Builtin::BIstrndup:
|
2012-01-17 08:37:07 +08:00
|
|
|
return Builtin::BIstrndup;
|
2012-01-14 05:52:01 +08:00
|
|
|
|
2012-02-02 03:08:57 +08:00
|
|
|
case Builtin::BI__builtin_strlen:
|
|
|
|
case Builtin::BIstrlen:
|
|
|
|
return Builtin::BIstrlen;
|
|
|
|
|
2012-01-14 05:52:01 +08:00
|
|
|
default:
|
2013-02-14 09:47:04 +08:00
|
|
|
if (isExternC()) {
|
2012-01-14 05:52:01 +08:00
|
|
|
if (FnInfo->isStr("memset"))
|
2012-01-17 08:37:07 +08:00
|
|
|
return Builtin::BImemset;
|
2012-01-14 05:52:01 +08:00
|
|
|
else if (FnInfo->isStr("memcpy"))
|
2012-01-17 08:37:07 +08:00
|
|
|
return Builtin::BImemcpy;
|
2012-01-14 05:52:01 +08:00
|
|
|
else if (FnInfo->isStr("memmove"))
|
2012-01-17 08:37:07 +08:00
|
|
|
return Builtin::BImemmove;
|
2012-01-14 05:52:01 +08:00
|
|
|
else if (FnInfo->isStr("memcmp"))
|
2012-01-17 08:37:07 +08:00
|
|
|
return Builtin::BImemcmp;
|
2012-01-14 05:52:01 +08:00
|
|
|
else if (FnInfo->isStr("strncpy"))
|
2012-01-17 08:37:07 +08:00
|
|
|
return Builtin::BIstrncpy;
|
2012-01-14 05:52:01 +08:00
|
|
|
else if (FnInfo->isStr("strncmp"))
|
2012-01-17 08:37:07 +08:00
|
|
|
return Builtin::BIstrncmp;
|
2012-01-14 05:52:01 +08:00
|
|
|
else if (FnInfo->isStr("strncasecmp"))
|
2012-01-17 08:37:07 +08:00
|
|
|
return Builtin::BIstrncasecmp;
|
2012-01-14 05:52:01 +08:00
|
|
|
else if (FnInfo->isStr("strncat"))
|
2012-01-17 08:37:07 +08:00
|
|
|
return Builtin::BIstrncat;
|
2012-01-14 05:52:01 +08:00
|
|
|
else if (FnInfo->isStr("strndup"))
|
2012-01-17 08:37:07 +08:00
|
|
|
return Builtin::BIstrndup;
|
2012-02-02 03:08:57 +08:00
|
|
|
else if (FnInfo->isStr("strlen"))
|
|
|
|
return Builtin::BIstrlen;
|
2012-01-14 05:52:01 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2012-01-17 08:37:07 +08:00
|
|
|
return 0;
|
2012-01-14 05:52:01 +08:00
|
|
|
}
|
|
|
|
|
2010-01-27 06:01:41 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// FieldDecl Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2011-01-12 17:06:06 +08:00
|
|
|
FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC,
|
2011-03-08 16:55:46 +08:00
|
|
|
SourceLocation StartLoc, SourceLocation IdLoc,
|
|
|
|
IdentifierInfo *Id, QualType T,
|
2011-06-12 01:19:42 +08:00
|
|
|
TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
|
2012-06-10 11:12:00 +08:00
|
|
|
InClassInitStyle InitStyle) {
|
2013-11-22 17:01:48 +08:00
|
|
|
return new (C, DC) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo,
|
|
|
|
BW, Mutable, InitStyle);
|
2010-01-27 06:01:41 +08:00
|
|
|
}
|
|
|
|
|
2012-01-06 05:55:30 +08:00
|
|
|
FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
|
2014-05-12 13:36:57 +08:00
|
|
|
return new (C, ID) FieldDecl(Field, nullptr, SourceLocation(),
|
|
|
|
SourceLocation(), nullptr, QualType(), nullptr,
|
|
|
|
nullptr, false, ICIS_NoInit);
|
2012-01-06 05:55:30 +08:00
|
|
|
}
|
|
|
|
|
2010-01-27 06:01:41 +08:00
|
|
|
bool FieldDecl::isAnonymousStructOrUnion() const {
|
|
|
|
if (!isImplicit() || getDeclName())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (const RecordType *Record = getType()->getAs<RecordType>())
|
|
|
|
return Record->getDecl()->isAnonymousStructOrUnion();
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-10-11 02:28:20 +08:00
|
|
|
unsigned FieldDecl::getBitWidthValue(const ASTContext &Ctx) const {
|
|
|
|
assert(isBitField() && "not a bitfield");
|
2014-10-11 02:44:34 +08:00
|
|
|
Expr *BitWidth = static_cast<Expr *>(InitStorage.getPointer());
|
2011-10-11 02:28:20 +08:00
|
|
|
return BitWidth->EvaluateKnownConstInt(Ctx).getZExtValue();
|
|
|
|
}
|
|
|
|
|
2011-01-20 15:57:12 +08:00
|
|
|
unsigned FieldDecl::getFieldIndex() const {
|
2013-10-07 16:02:11 +08:00
|
|
|
const FieldDecl *Canonical = getCanonicalDecl();
|
|
|
|
if (Canonical != this)
|
|
|
|
return Canonical->getFieldIndex();
|
|
|
|
|
2011-01-20 15:57:12 +08:00
|
|
|
if (CachedFieldIndex) return CachedFieldIndex - 1;
|
|
|
|
|
2011-11-10 14:34:14 +08:00
|
|
|
unsigned Index = 0;
|
2011-04-29 06:49:46 +08:00
|
|
|
const RecordDecl *RD = getParent();
|
2011-11-10 14:34:14 +08:00
|
|
|
|
2014-08-22 00:06:57 +08:00
|
|
|
for (auto *Field : RD->fields()) {
|
|
|
|
Field->getCanonicalDecl()->CachedFieldIndex = Index + 1;
|
|
|
|
++Index;
|
|
|
|
}
|
2011-01-20 15:57:12 +08:00
|
|
|
|
2011-11-10 14:34:14 +08:00
|
|
|
assert(CachedFieldIndex && "failed to find field in parent");
|
|
|
|
return CachedFieldIndex - 1;
|
2011-01-20 15:57:12 +08:00
|
|
|
}
|
|
|
|
|
2011-03-08 19:07:11 +08:00
|
|
|
SourceRange FieldDecl::getSourceRange() const {
|
2014-10-11 02:44:34 +08:00
|
|
|
switch (InitStorage.getInt()) {
|
|
|
|
// All three of these cases store an optional Expr*.
|
|
|
|
case ISK_BitWidthOrNothing:
|
|
|
|
case ISK_InClassCopyInit:
|
|
|
|
case ISK_InClassListInit:
|
|
|
|
if (const Expr *E = static_cast<const Expr *>(InitStorage.getPointer()))
|
|
|
|
return SourceRange(getInnerLocStart(), E->getLocEnd());
|
|
|
|
// FALLTHROUGH
|
2011-03-08 19:07:11 +08:00
|
|
|
|
2014-10-11 02:44:34 +08:00
|
|
|
case ISK_CapturedVLAType:
|
|
|
|
return DeclaratorDecl::getSourceRange();
|
|
|
|
}
|
|
|
|
llvm_unreachable("bad init storage kind");
|
2014-08-28 12:28:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void FieldDecl::setCapturedVLAType(const VariableArrayType *VLAType) {
|
2014-11-01 01:18:09 +08:00
|
|
|
assert((getParent()->isLambda() || getParent()->isCapturedRecord()) &&
|
2014-10-29 20:21:55 +08:00
|
|
|
"capturing type in non-lambda or captured record.");
|
2014-10-11 02:44:34 +08:00
|
|
|
assert(InitStorage.getInt() == ISK_BitWidthOrNothing &&
|
|
|
|
InitStorage.getPointer() == nullptr &&
|
2014-08-28 12:28:19 +08:00
|
|
|
"bit width, initializer or captured type already set");
|
2014-10-11 02:44:34 +08:00
|
|
|
InitStorage.setPointerAndInt(const_cast<VariableArrayType *>(VLAType),
|
|
|
|
ISK_CapturedVLAType);
|
2014-08-28 12:28:19 +08:00
|
|
|
}
|
|
|
|
|
Change struct forward declarations and definitions to use unique RecordDecls, as opposed to creating a single RecordDecl and reusing it.
This change effects both RecordDecls and CXXRecordDecls, but does not effect EnumDecls (yet).
The motivation of this patch is as follows:
- Capture more source information, necessary for refactoring/rewriting clients.
- Pave the way to resolve ownership issues with RecordDecls with the forthcoming
addition of DeclGroups.
Current caveats:
- Until DeclGroups are in place, we will leak RecordDecls not explicitly
referenced by the AST. For example:
typedef struct { ... } x;
The RecordDecl for the struct will be leaked because the TypedefDecl doesn't
refer to it. This will be solved with DeclGroups.
- This patch also (temporarily) breaks CodeGen. More below.
High-level changes:
- As before, TagType still refers to a TagDecl, but it doesn't own it. When
a struct/union/class is first referenced, a RecordType and RecordDecl are
created for it, and the RecordType refers to that RecordDecl. Later, if
a new RecordDecl is created, the pointer to a RecordDecl in RecordType is
updated to point to the RecordDecl that defines the struct/union/class.
- TagDecl and RecordDecl now how a method 'getDefinition()' to return the
TagDecl*/RecordDecl* that refers to the TagDecl* that defines a particular
enum/struct/class/union. This is useful from going from a RecordDecl* that
defines a forward declaration to the RecordDecl* that provides the actual
definition. Note that this also works for EnumDecls, except that in this case
there is no distinction between forward declarations and definitions (yet).
- Clients should no longer assume that 'isDefinition()' returns true from a
RecordDecl if the corresponding struct/union/class has been defined.
isDefinition() only returns true if a particular RecordDecl is the defining
Decl. Use 'getDefinition()' instead to determine if a struct has been defined.
- The main changes to Sema happen in ActOnTag. To make the changes more
incremental, I split off the processing of enums and structs et al into two
code paths. Enums use the original code path (which is in ActOnTag) and
structs use the ActOnTagStruct. Eventually the two code paths will be merged,
but the idea was to preserve the original logic both for comparison and not to
change the logic for both enums and structs all at once.
- There is NO CHAINING of RecordDecls for the same RecordType. All RecordDecls
that correspond to the same type simply have a pointer to that type. If we
need to figure out what are all the RecordDecls for a given type we can build
a backmap.
- The diff in CXXRecordDecl.[cpp,h] is actually very small; it just mimics the
changes to RecordDecl. For some reason 'svn' marks the entire file as changed.
Why is CodeGen broken:
- Codegen assumes that there is an equivalence between RecordDecl* and
RecordType*. This was true before because we only created one RecordDecl* for
a given RecordType*, but it is no longer true. I believe this shouldn't be too
hard to change, but the patch was big enough as it is.
I have tested this patch on both the clang test suite, and by running the static analyzer over Postgresql and a large Apple-internal project (mix of Objective-C and C).
llvm-svn: 55839
2008-09-06 01:16:31 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2009-01-07 08:43:41 +08:00
|
|
|
// TagDecl Implementation
|
Change struct forward declarations and definitions to use unique RecordDecls, as opposed to creating a single RecordDecl and reusing it.
This change effects both RecordDecls and CXXRecordDecls, but does not effect EnumDecls (yet).
The motivation of this patch is as follows:
- Capture more source information, necessary for refactoring/rewriting clients.
- Pave the way to resolve ownership issues with RecordDecls with the forthcoming
addition of DeclGroups.
Current caveats:
- Until DeclGroups are in place, we will leak RecordDecls not explicitly
referenced by the AST. For example:
typedef struct { ... } x;
The RecordDecl for the struct will be leaked because the TypedefDecl doesn't
refer to it. This will be solved with DeclGroups.
- This patch also (temporarily) breaks CodeGen. More below.
High-level changes:
- As before, TagType still refers to a TagDecl, but it doesn't own it. When
a struct/union/class is first referenced, a RecordType and RecordDecl are
created for it, and the RecordType refers to that RecordDecl. Later, if
a new RecordDecl is created, the pointer to a RecordDecl in RecordType is
updated to point to the RecordDecl that defines the struct/union/class.
- TagDecl and RecordDecl now how a method 'getDefinition()' to return the
TagDecl*/RecordDecl* that refers to the TagDecl* that defines a particular
enum/struct/class/union. This is useful from going from a RecordDecl* that
defines a forward declaration to the RecordDecl* that provides the actual
definition. Note that this also works for EnumDecls, except that in this case
there is no distinction between forward declarations and definitions (yet).
- Clients should no longer assume that 'isDefinition()' returns true from a
RecordDecl if the corresponding struct/union/class has been defined.
isDefinition() only returns true if a particular RecordDecl is the defining
Decl. Use 'getDefinition()' instead to determine if a struct has been defined.
- The main changes to Sema happen in ActOnTag. To make the changes more
incremental, I split off the processing of enums and structs et al into two
code paths. Enums use the original code path (which is in ActOnTag) and
structs use the ActOnTagStruct. Eventually the two code paths will be merged,
but the idea was to preserve the original logic both for comparison and not to
change the logic for both enums and structs all at once.
- There is NO CHAINING of RecordDecls for the same RecordType. All RecordDecls
that correspond to the same type simply have a pointer to that type. If we
need to figure out what are all the RecordDecls for a given type we can build
a backmap.
- The diff in CXXRecordDecl.[cpp,h] is actually very small; it just mimics the
changes to RecordDecl. For some reason 'svn' marks the entire file as changed.
Why is CodeGen broken:
- Codegen assumes that there is an equivalence between RecordDecl* and
RecordType*. This was true before because we only created one RecordDecl* for
a given RecordType*, but it is no longer true. I believe this shouldn't be too
hard to change, but the patch was big enough as it is.
I have tested this patch on both the clang test suite, and by running the static analyzer over Postgresql and a large Apple-internal project (mix of Objective-C and C).
llvm-svn: 55839
2008-09-06 01:16:31 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-07-07 02:42:40 +08:00
|
|
|
SourceLocation TagDecl::getOuterLocStart() const {
|
|
|
|
return getTemplateOrInnerLocStart(this);
|
|
|
|
}
|
|
|
|
|
2009-07-14 11:17:17 +08:00
|
|
|
SourceRange TagDecl::getSourceRange() const {
|
|
|
|
SourceLocation E = RBraceLoc.isValid() ? RBraceLoc : getLocation();
|
2010-07-07 02:42:40 +08:00
|
|
|
return SourceRange(getOuterLocStart(), E);
|
2009-07-14 11:17:17 +08:00
|
|
|
}
|
|
|
|
|
2013-10-17 23:37:26 +08:00
|
|
|
TagDecl *TagDecl::getCanonicalDecl() { return getFirstDecl(); }
|
2009-07-18 08:34:07 +08:00
|
|
|
|
2013-03-13 05:06:00 +08:00
|
|
|
void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) {
|
2013-09-18 07:57:10 +08:00
|
|
|
NamedDeclOrQualifier = TDD;
|
2014-04-24 06:03:04 +08:00
|
|
|
if (const Type *T = getTypeForDecl()) {
|
|
|
|
(void)T;
|
2014-04-24 02:20:42 +08:00
|
|
|
assert(T->isLinkageValid());
|
2014-04-24 06:03:04 +08:00
|
|
|
}
|
2013-03-14 11:07:35 +08:00
|
|
|
assert(isLinkageValid());
|
2010-05-20 02:39:18 +08:00
|
|
|
}
|
|
|
|
|
2009-01-17 08:42:38 +08:00
|
|
|
void TagDecl::startDefinition() {
|
2010-08-03 02:27:05 +08:00
|
|
|
IsBeingDefined = true;
|
2010-02-05 06:26:26 +08:00
|
|
|
|
2012-11-14 09:52:05 +08:00
|
|
|
if (CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(this)) {
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
struct CXXRecordDecl::DefinitionData *Data =
|
2010-02-05 06:26:26 +08:00
|
|
|
new (getASTContext()) struct CXXRecordDecl::DefinitionData(D);
|
2014-03-07 07:45:36 +08:00
|
|
|
for (auto I : redecls())
|
2014-05-23 07:19:02 +08:00
|
|
|
cast<CXXRecordDecl>(I)->DefinitionData = Data;
|
2010-02-05 06:26:26 +08:00
|
|
|
}
|
2009-01-17 08:42:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void TagDecl::completeDefinition() {
|
2010-02-05 09:33:36 +08:00
|
|
|
assert((!isa<CXXRecordDecl>(this) ||
|
|
|
|
cast<CXXRecordDecl>(this)->hasDefinition()) &&
|
|
|
|
"definition completed but not started");
|
|
|
|
|
2011-10-07 14:10:15 +08:00
|
|
|
IsCompleteDefinition = true;
|
2010-08-03 02:27:05 +08:00
|
|
|
IsBeingDefined = false;
|
2010-10-25 01:26:50 +08:00
|
|
|
|
|
|
|
if (ASTMutationListener *L = getASTMutationListener())
|
|
|
|
L->CompletedTagDefinition(this);
|
2009-01-17 08:42:38 +08:00
|
|
|
}
|
|
|
|
|
2011-10-07 14:10:15 +08:00
|
|
|
TagDecl *TagDecl::getDefinition() const {
|
|
|
|
if (isCompleteDefinition())
|
2009-07-30 07:36:44 +08:00
|
|
|
return const_cast<TagDecl *>(this);
|
Ensure that type definitions present in just-loaded modules are
visible.
The basic problem here is that a given translation unit can use
forward declarations to form pointers to a given type, say,
class X;
X *x;
and then import a module that includes a definition of X:
import XDef;
We will then fail when attempting to access a member of X, e.g.,
x->method()
because the AST reader did not know to look for a default of a class
named X within the new module.
This implementation is a bit of a C-centric hack, because the only
definitions that can have this property are enums, structs, unions,
Objective-C classes, and Objective-C protocols, and all of those are
either visible at the top-level or can't be defined later. Hence, we
can use the out-of-date-ness of the name and the identifier-update
mechanism to force the update.
In C++, we will not be so lucky, and will need a more advanced
solution, because the definitions could be in namespaces defined in
two different modules, e.g.,
// module 1
namespace N { struct X; }
// module 2
namespace N { struct X { /* ... */ }; }
One possible implementation here is for C++ to extend the information
associated with each identifier table to include the declaration IDs
of any definitions associated with that name, regardless of
context. We would have to eagerly load those definitions.
llvm-svn: 174794
2013-02-09 09:35:03 +08:00
|
|
|
|
|
|
|
// If it's possible for us to have an out-of-date definition, check now.
|
|
|
|
if (MayHaveOutOfDateDef) {
|
|
|
|
if (IdentifierInfo *II = getIdentifier()) {
|
|
|
|
if (II->isOutOfDate()) {
|
|
|
|
updateOutOfDate(*II);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-20 05:54:32 +08:00
|
|
|
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(this))
|
|
|
|
return CXXRD->getDefinition();
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2014-03-07 07:45:36 +08:00
|
|
|
for (auto R : redecls())
|
2011-10-07 14:10:15 +08:00
|
|
|
if (R->isCompleteDefinition())
|
2014-03-07 07:45:36 +08:00
|
|
|
return R;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2014-05-12 13:36:57 +08:00
|
|
|
return nullptr;
|
Change struct forward declarations and definitions to use unique RecordDecls, as opposed to creating a single RecordDecl and reusing it.
This change effects both RecordDecls and CXXRecordDecls, but does not effect EnumDecls (yet).
The motivation of this patch is as follows:
- Capture more source information, necessary for refactoring/rewriting clients.
- Pave the way to resolve ownership issues with RecordDecls with the forthcoming
addition of DeclGroups.
Current caveats:
- Until DeclGroups are in place, we will leak RecordDecls not explicitly
referenced by the AST. For example:
typedef struct { ... } x;
The RecordDecl for the struct will be leaked because the TypedefDecl doesn't
refer to it. This will be solved with DeclGroups.
- This patch also (temporarily) breaks CodeGen. More below.
High-level changes:
- As before, TagType still refers to a TagDecl, but it doesn't own it. When
a struct/union/class is first referenced, a RecordType and RecordDecl are
created for it, and the RecordType refers to that RecordDecl. Later, if
a new RecordDecl is created, the pointer to a RecordDecl in RecordType is
updated to point to the RecordDecl that defines the struct/union/class.
- TagDecl and RecordDecl now how a method 'getDefinition()' to return the
TagDecl*/RecordDecl* that refers to the TagDecl* that defines a particular
enum/struct/class/union. This is useful from going from a RecordDecl* that
defines a forward declaration to the RecordDecl* that provides the actual
definition. Note that this also works for EnumDecls, except that in this case
there is no distinction between forward declarations and definitions (yet).
- Clients should no longer assume that 'isDefinition()' returns true from a
RecordDecl if the corresponding struct/union/class has been defined.
isDefinition() only returns true if a particular RecordDecl is the defining
Decl. Use 'getDefinition()' instead to determine if a struct has been defined.
- The main changes to Sema happen in ActOnTag. To make the changes more
incremental, I split off the processing of enums and structs et al into two
code paths. Enums use the original code path (which is in ActOnTag) and
structs use the ActOnTagStruct. Eventually the two code paths will be merged,
but the idea was to preserve the original logic both for comparison and not to
change the logic for both enums and structs all at once.
- There is NO CHAINING of RecordDecls for the same RecordType. All RecordDecls
that correspond to the same type simply have a pointer to that type. If we
need to figure out what are all the RecordDecls for a given type we can build
a backmap.
- The diff in CXXRecordDecl.[cpp,h] is actually very small; it just mimics the
changes to RecordDecl. For some reason 'svn' marks the entire file as changed.
Why is CodeGen broken:
- Codegen assumes that there is an equivalence between RecordDecl* and
RecordType*. This was true before because we only created one RecordDecl* for
a given RecordType*, but it is no longer true. I believe this shouldn't be too
hard to change, but the patch was big enough as it is.
I have tested this patch on both the clang test suite, and by running the static analyzer over Postgresql and a large Apple-internal project (mix of Objective-C and C).
llvm-svn: 55839
2008-09-06 01:16:31 +08:00
|
|
|
}
|
|
|
|
|
2011-02-25 10:25:35 +08:00
|
|
|
void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
|
|
|
|
if (QualifierLoc) {
|
2010-03-15 18:12:16 +08:00
|
|
|
// Make sure the extended qualifier info is allocated.
|
|
|
|
if (!hasExtInfo())
|
2013-09-18 07:57:10 +08:00
|
|
|
NamedDeclOrQualifier = new (getASTContext()) ExtInfo;
|
2010-03-15 18:12:16 +08:00
|
|
|
// Set qualifier info.
|
2011-02-25 10:25:35 +08:00
|
|
|
getExtInfo()->QualifierLoc = QualifierLoc;
|
2011-08-18 07:08:45 +08:00
|
|
|
} else {
|
2010-03-15 18:12:16 +08:00
|
|
|
// Here Qualifier == 0, i.e., we are removing the qualifier (if any).
|
|
|
|
if (hasExtInfo()) {
|
2011-03-18 23:16:37 +08:00
|
|
|
if (getExtInfo()->NumTemplParamLists == 0) {
|
|
|
|
getASTContext().Deallocate(getExtInfo());
|
2014-05-12 13:36:57 +08:00
|
|
|
NamedDeclOrQualifier = (TypedefNameDecl*)nullptr;
|
2011-03-18 23:16:37 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
getExtInfo()->QualifierLoc = QualifierLoc;
|
2010-03-15 18:12:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-03-18 23:16:37 +08:00
|
|
|
void TagDecl::setTemplateParameterListsInfo(ASTContext &Context,
|
|
|
|
unsigned NumTPLists,
|
|
|
|
TemplateParameterList **TPLists) {
|
|
|
|
assert(NumTPLists > 0);
|
|
|
|
// Make sure the extended decl info is allocated.
|
|
|
|
if (!hasExtInfo())
|
|
|
|
// Allocate external info struct.
|
2013-09-18 07:57:10 +08:00
|
|
|
NamedDeclOrQualifier = new (getASTContext()) ExtInfo;
|
2011-03-18 23:16:37 +08:00
|
|
|
// Set the template parameter lists info.
|
|
|
|
getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists);
|
|
|
|
}
|
|
|
|
|
2010-01-27 06:01:41 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// EnumDecl Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2011-12-20 10:48:34 +08:00
|
|
|
void EnumDecl::anchor() { }
|
|
|
|
|
2011-03-09 22:09:51 +08:00
|
|
|
EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC,
|
|
|
|
SourceLocation StartLoc, SourceLocation IdLoc,
|
|
|
|
IdentifierInfo *Id,
|
2010-12-04 02:54:17 +08:00
|
|
|
EnumDecl *PrevDecl, bool IsScoped,
|
|
|
|
bool IsScopedUsingClassTag, bool IsFixed) {
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
EnumDecl *Enum = new (C, DC) EnumDecl(C, DC, StartLoc, IdLoc, Id, PrevDecl,
|
2013-11-22 17:01:48 +08:00
|
|
|
IsScoped, IsScopedUsingClassTag,
|
|
|
|
IsFixed);
|
Ensure that type definitions present in just-loaded modules are
visible.
The basic problem here is that a given translation unit can use
forward declarations to form pointers to a given type, say,
class X;
X *x;
and then import a module that includes a definition of X:
import XDef;
We will then fail when attempting to access a member of X, e.g.,
x->method()
because the AST reader did not know to look for a default of a class
named X within the new module.
This implementation is a bit of a C-centric hack, because the only
definitions that can have this property are enums, structs, unions,
Objective-C classes, and Objective-C protocols, and all of those are
either visible at the top-level or can't be defined later. Hence, we
can use the out-of-date-ness of the name and the identifier-update
mechanism to force the update.
In C++, we will not be so lucky, and will need a more advanced
solution, because the definitions could be in namespaces defined in
two different modules, e.g.,
// module 1
namespace N { struct X; }
// module 2
namespace N { struct X { /* ... */ }; }
One possible implementation here is for C++ to extend the information
associated with each identifier table to include the declaration IDs
of any definitions associated with that name, regardless of
context. We would have to eagerly load those definitions.
llvm-svn: 174794
2013-02-09 09:35:03 +08:00
|
|
|
Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules;
|
2010-01-27 06:01:41 +08:00
|
|
|
C.getTypeDeclType(Enum, PrevDecl);
|
|
|
|
return Enum;
|
|
|
|
}
|
|
|
|
|
2012-01-06 05:55:30 +08:00
|
|
|
EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
EnumDecl *Enum =
|
|
|
|
new (C, ID) EnumDecl(C, nullptr, SourceLocation(), SourceLocation(),
|
|
|
|
nullptr, nullptr, false, false, false);
|
Ensure that type definitions present in just-loaded modules are
visible.
The basic problem here is that a given translation unit can use
forward declarations to form pointers to a given type, say,
class X;
X *x;
and then import a module that includes a definition of X:
import XDef;
We will then fail when attempting to access a member of X, e.g.,
x->method()
because the AST reader did not know to look for a default of a class
named X within the new module.
This implementation is a bit of a C-centric hack, because the only
definitions that can have this property are enums, structs, unions,
Objective-C classes, and Objective-C protocols, and all of those are
either visible at the top-level or can't be defined later. Hence, we
can use the out-of-date-ness of the name and the identifier-update
mechanism to force the update.
In C++, we will not be so lucky, and will need a more advanced
solution, because the definitions could be in namespaces defined in
two different modules, e.g.,
// module 1
namespace N { struct X; }
// module 2
namespace N { struct X { /* ... */ }; }
One possible implementation here is for C++ to extend the information
associated with each identifier table to include the declaration IDs
of any definitions associated with that name, regardless of
context. We would have to eagerly load those definitions.
llvm-svn: 174794
2013-02-09 09:35:03 +08:00
|
|
|
Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules;
|
|
|
|
return Enum;
|
2010-07-02 19:54:55 +08:00
|
|
|
}
|
|
|
|
|
2014-01-06 19:31:18 +08:00
|
|
|
SourceRange EnumDecl::getIntegerTypeRange() const {
|
|
|
|
if (const TypeSourceInfo *TI = getIntegerTypeSourceInfo())
|
|
|
|
return TI->getTypeLoc().getSourceRange();
|
|
|
|
return SourceRange();
|
|
|
|
}
|
|
|
|
|
2010-02-11 09:19:42 +08:00
|
|
|
void EnumDecl::completeDefinition(QualType NewType,
|
2010-05-06 16:49:23 +08:00
|
|
|
QualType NewPromotionType,
|
|
|
|
unsigned NumPositiveBits,
|
|
|
|
unsigned NumNegativeBits) {
|
2011-10-07 14:10:15 +08:00
|
|
|
assert(!isCompleteDefinition() && "Cannot redefine enums!");
|
2010-10-09 07:50:27 +08:00
|
|
|
if (!IntegerType)
|
|
|
|
IntegerType = NewType.getTypePtr();
|
2010-01-27 06:01:41 +08:00
|
|
|
PromotionType = NewPromotionType;
|
2010-05-06 16:49:23 +08:00
|
|
|
setNumPositiveBits(NumPositiveBits);
|
|
|
|
setNumNegativeBits(NumNegativeBits);
|
2010-01-27 06:01:41 +08:00
|
|
|
TagDecl::completeDefinition();
|
|
|
|
}
|
|
|
|
|
2012-03-23 11:33:32 +08:00
|
|
|
TemplateSpecializationKind EnumDecl::getTemplateSpecializationKind() const {
|
|
|
|
if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
|
|
|
|
return MSI->getTemplateSpecializationKind();
|
|
|
|
|
|
|
|
return TSK_Undeclared;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EnumDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
|
|
|
|
SourceLocation PointOfInstantiation) {
|
|
|
|
MemberSpecializationInfo *MSI = getMemberSpecializationInfo();
|
|
|
|
assert(MSI && "Not an instantiated member enumeration?");
|
|
|
|
MSI->setTemplateSpecializationKind(TSK);
|
|
|
|
if (TSK != TSK_ExplicitSpecialization &&
|
|
|
|
PointOfInstantiation.isValid() &&
|
|
|
|
MSI->getPointOfInstantiation().isInvalid())
|
|
|
|
MSI->setPointOfInstantiation(PointOfInstantiation);
|
|
|
|
}
|
|
|
|
|
2012-03-15 07:13:10 +08:00
|
|
|
EnumDecl *EnumDecl::getInstantiatedFromMemberEnum() const {
|
|
|
|
if (SpecializationInfo)
|
|
|
|
return cast<EnumDecl>(SpecializationInfo->getInstantiatedFrom());
|
|
|
|
|
2014-05-12 13:36:57 +08:00
|
|
|
return nullptr;
|
2012-03-15 07:13:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void EnumDecl::setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
|
|
|
|
TemplateSpecializationKind TSK) {
|
|
|
|
assert(!SpecializationInfo && "Member enum is already a specialization");
|
|
|
|
SpecializationInfo = new (C) MemberSpecializationInfo(ED, TSK);
|
|
|
|
}
|
|
|
|
|
2008-03-31 08:36:02 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// RecordDecl Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
2007-01-25 12:52:46 +08:00
|
|
|
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
RecordDecl::RecordDecl(Kind DK, TagKind TK, const ASTContext &C,
|
|
|
|
DeclContext *DC, SourceLocation StartLoc,
|
|
|
|
SourceLocation IdLoc, IdentifierInfo *Id,
|
|
|
|
RecordDecl *PrevDecl)
|
|
|
|
: TagDecl(DK, TK, C, DC, IdLoc, Id, PrevDecl, StartLoc) {
|
2008-09-03 05:12:32 +08:00
|
|
|
HasFlexibleArrayMember = false;
|
2009-01-07 08:43:41 +08:00
|
|
|
AnonymousStructOrUnion = false;
|
2009-07-08 09:18:33 +08:00
|
|
|
HasObjectMember = false;
|
2013-01-26 07:57:05 +08:00
|
|
|
HasVolatileMember = false;
|
2010-10-15 04:14:34 +08:00
|
|
|
LoadedFieldsFromExternalStorage = false;
|
2008-09-03 05:12:32 +08:00
|
|
|
assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
|
|
|
|
}
|
|
|
|
|
2011-01-12 17:06:06 +08:00
|
|
|
RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC,
|
2011-03-09 22:09:51 +08:00
|
|
|
SourceLocation StartLoc, SourceLocation IdLoc,
|
|
|
|
IdentifierInfo *Id, RecordDecl* PrevDecl) {
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
RecordDecl *R = new (C, DC) RecordDecl(Record, TK, C, DC,
|
|
|
|
StartLoc, IdLoc, Id, PrevDecl);
|
Ensure that type definitions present in just-loaded modules are
visible.
The basic problem here is that a given translation unit can use
forward declarations to form pointers to a given type, say,
class X;
X *x;
and then import a module that includes a definition of X:
import XDef;
We will then fail when attempting to access a member of X, e.g.,
x->method()
because the AST reader did not know to look for a default of a class
named X within the new module.
This implementation is a bit of a C-centric hack, because the only
definitions that can have this property are enums, structs, unions,
Objective-C classes, and Objective-C protocols, and all of those are
either visible at the top-level or can't be defined later. Hence, we
can use the out-of-date-ness of the name and the identifier-update
mechanism to force the update.
In C++, we will not be so lucky, and will need a more advanced
solution, because the definitions could be in namespaces defined in
two different modules, e.g.,
// module 1
namespace N { struct X; }
// module 2
namespace N { struct X { /* ... */ }; }
One possible implementation here is for C++ to extend the information
associated with each identifier table to include the declaration IDs
of any definitions associated with that name, regardless of
context. We would have to eagerly load those definitions.
llvm-svn: 174794
2013-02-09 09:35:03 +08:00
|
|
|
R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
|
|
|
|
|
Change struct forward declarations and definitions to use unique RecordDecls, as opposed to creating a single RecordDecl and reusing it.
This change effects both RecordDecls and CXXRecordDecls, but does not effect EnumDecls (yet).
The motivation of this patch is as follows:
- Capture more source information, necessary for refactoring/rewriting clients.
- Pave the way to resolve ownership issues with RecordDecls with the forthcoming
addition of DeclGroups.
Current caveats:
- Until DeclGroups are in place, we will leak RecordDecls not explicitly
referenced by the AST. For example:
typedef struct { ... } x;
The RecordDecl for the struct will be leaked because the TypedefDecl doesn't
refer to it. This will be solved with DeclGroups.
- This patch also (temporarily) breaks CodeGen. More below.
High-level changes:
- As before, TagType still refers to a TagDecl, but it doesn't own it. When
a struct/union/class is first referenced, a RecordType and RecordDecl are
created for it, and the RecordType refers to that RecordDecl. Later, if
a new RecordDecl is created, the pointer to a RecordDecl in RecordType is
updated to point to the RecordDecl that defines the struct/union/class.
- TagDecl and RecordDecl now how a method 'getDefinition()' to return the
TagDecl*/RecordDecl* that refers to the TagDecl* that defines a particular
enum/struct/class/union. This is useful from going from a RecordDecl* that
defines a forward declaration to the RecordDecl* that provides the actual
definition. Note that this also works for EnumDecls, except that in this case
there is no distinction between forward declarations and definitions (yet).
- Clients should no longer assume that 'isDefinition()' returns true from a
RecordDecl if the corresponding struct/union/class has been defined.
isDefinition() only returns true if a particular RecordDecl is the defining
Decl. Use 'getDefinition()' instead to determine if a struct has been defined.
- The main changes to Sema happen in ActOnTag. To make the changes more
incremental, I split off the processing of enums and structs et al into two
code paths. Enums use the original code path (which is in ActOnTag) and
structs use the ActOnTagStruct. Eventually the two code paths will be merged,
but the idea was to preserve the original logic both for comparison and not to
change the logic for both enums and structs all at once.
- There is NO CHAINING of RecordDecls for the same RecordType. All RecordDecls
that correspond to the same type simply have a pointer to that type. If we
need to figure out what are all the RecordDecls for a given type we can build
a backmap.
- The diff in CXXRecordDecl.[cpp,h] is actually very small; it just mimics the
changes to RecordDecl. For some reason 'svn' marks the entire file as changed.
Why is CodeGen broken:
- Codegen assumes that there is an equivalence between RecordDecl* and
RecordType*. This was true before because we only created one RecordDecl* for
a given RecordType*, but it is no longer true. I believe this shouldn't be too
hard to change, but the patch was big enough as it is.
I have tested this patch on both the clang test suite, and by running the static analyzer over Postgresql and a large Apple-internal project (mix of Objective-C and C).
llvm-svn: 55839
2008-09-06 01:16:31 +08:00
|
|
|
C.getTypeDeclType(R, PrevDecl);
|
|
|
|
return R;
|
2008-09-03 05:12:32 +08:00
|
|
|
}
|
|
|
|
|
2012-01-06 05:55:30 +08:00
|
|
|
RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
RecordDecl *R =
|
|
|
|
new (C, ID) RecordDecl(Record, TTK_Struct, C, nullptr, SourceLocation(),
|
|
|
|
SourceLocation(), nullptr, nullptr);
|
Ensure that type definitions present in just-loaded modules are
visible.
The basic problem here is that a given translation unit can use
forward declarations to form pointers to a given type, say,
class X;
X *x;
and then import a module that includes a definition of X:
import XDef;
We will then fail when attempting to access a member of X, e.g.,
x->method()
because the AST reader did not know to look for a default of a class
named X within the new module.
This implementation is a bit of a C-centric hack, because the only
definitions that can have this property are enums, structs, unions,
Objective-C classes, and Objective-C protocols, and all of those are
either visible at the top-level or can't be defined later. Hence, we
can use the out-of-date-ness of the name and the identifier-update
mechanism to force the update.
In C++, we will not be so lucky, and will need a more advanced
solution, because the definitions could be in namespaces defined in
two different modules, e.g.,
// module 1
namespace N { struct X; }
// module 2
namespace N { struct X { /* ... */ }; }
One possible implementation here is for C++ to extend the information
associated with each identifier table to include the declaration IDs
of any definitions associated with that name, regardless of
context. We would have to eagerly load those definitions.
llvm-svn: 174794
2013-02-09 09:35:03 +08:00
|
|
|
R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
|
|
|
|
return R;
|
2010-07-02 19:54:55 +08:00
|
|
|
}
|
|
|
|
|
2009-03-25 23:59:44 +08:00
|
|
|
bool RecordDecl::isInjectedClassName() const {
|
2009-09-09 23:08:12 +08:00
|
|
|
return isImplicit() && getDeclName() && getDeclContext()->isRecord() &&
|
2009-03-25 23:59:44 +08:00
|
|
|
cast<RecordDecl>(getDeclContext())->getDeclName() == getDeclName();
|
|
|
|
}
|
|
|
|
|
2014-08-28 12:28:19 +08:00
|
|
|
bool RecordDecl::isLambda() const {
|
|
|
|
if (auto RD = dyn_cast<CXXRecordDecl>(this))
|
|
|
|
return RD->isLambda();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-10-29 20:21:55 +08:00
|
|
|
bool RecordDecl::isCapturedRecord() const {
|
|
|
|
return hasAttr<CapturedRecordAttr>();
|
|
|
|
}
|
|
|
|
|
|
|
|
void RecordDecl::setCapturedRecord() {
|
|
|
|
addAttr(CapturedRecordAttr::CreateImplicit(getASTContext()));
|
|
|
|
}
|
|
|
|
|
2010-10-15 04:14:34 +08:00
|
|
|
RecordDecl::field_iterator RecordDecl::field_begin() const {
|
|
|
|
if (hasExternalLexicalStorage() && !LoadedFieldsFromExternalStorage)
|
|
|
|
LoadFieldsFromExternalStorage();
|
|
|
|
|
|
|
|
return field_iterator(decl_iterator(FirstDecl));
|
|
|
|
}
|
|
|
|
|
2011-02-20 02:51:44 +08:00
|
|
|
/// completeDefinition - Notes that the definition of this type is now
|
|
|
|
/// complete.
|
|
|
|
void RecordDecl::completeDefinition() {
|
2011-10-07 14:10:15 +08:00
|
|
|
assert(!isCompleteDefinition() && "Cannot redefine record!");
|
2011-02-20 02:51:44 +08:00
|
|
|
TagDecl::completeDefinition();
|
|
|
|
}
|
|
|
|
|
2012-10-13 07:29:20 +08:00
|
|
|
/// isMsStruct - Get whether or not this record uses ms_struct layout.
|
|
|
|
/// This which can be turned on with an attribute, pragma, or the
|
|
|
|
/// -mms-bitfields command-line option.
|
|
|
|
bool RecordDecl::isMsStruct(const ASTContext &C) const {
|
2015-02-03 03:30:52 +08:00
|
|
|
return hasAttr<MSStructAttr>() || C.getLangOpts().MSBitfields == 1;
|
2012-10-13 07:29:20 +08:00
|
|
|
}
|
|
|
|
|
2012-09-11 06:04:22 +08:00
|
|
|
static bool isFieldOrIndirectField(Decl::Kind K) {
|
|
|
|
return FieldDecl::classofKind(K) || IndirectFieldDecl::classofKind(K);
|
|
|
|
}
|
|
|
|
|
2010-10-15 04:14:34 +08:00
|
|
|
void RecordDecl::LoadFieldsFromExternalStorage() const {
|
|
|
|
ExternalASTSource *Source = getASTContext().getExternalSource();
|
|
|
|
assert(hasExternalLexicalStorage() && Source && "No external storage?");
|
|
|
|
|
|
|
|
// Notify that we have a RecordDecl doing some initialization.
|
|
|
|
ExternalASTSource::Deserializing TheFields(Source);
|
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<Decl*, 64> Decls;
|
2011-07-16 05:46:17 +08:00
|
|
|
LoadedFieldsFromExternalStorage = true;
|
2012-09-11 06:04:22 +08:00
|
|
|
switch (Source->FindExternalLexicalDecls(this, isFieldOrIndirectField,
|
|
|
|
Decls)) {
|
2011-07-16 05:46:17 +08:00
|
|
|
case ELR_Success:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ELR_AlreadyLoaded:
|
|
|
|
case ELR_Failure:
|
2010-10-15 04:14:34 +08:00
|
|
|
return;
|
2011-07-16 05:46:17 +08:00
|
|
|
}
|
2010-10-15 04:14:34 +08:00
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
// Check that all decls we got were FieldDecls.
|
|
|
|
for (unsigned i=0, e=Decls.size(); i != e; ++i)
|
2012-09-11 06:04:22 +08:00
|
|
|
assert(isa<FieldDecl>(Decls[i]) || isa<IndirectFieldDecl>(Decls[i]));
|
2010-10-15 04:14:34 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
if (Decls.empty())
|
|
|
|
return;
|
|
|
|
|
2014-03-02 21:01:17 +08:00
|
|
|
std::tie(FirstDecl, LastDecl) = BuildDeclChain(Decls,
|
2011-10-08 05:55:43 +08:00
|
|
|
/*FieldsAlreadyLoaded=*/false);
|
2010-10-15 04:14:34 +08:00
|
|
|
}
|
|
|
|
|
2014-10-17 04:54:52 +08:00
|
|
|
bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const {
|
|
|
|
ASTContext &Context = getASTContext();
|
2014-11-08 06:29:38 +08:00
|
|
|
if (!Context.getLangOpts().Sanitize.has(SanitizerKind::Address) ||
|
2014-11-11 09:26:14 +08:00
|
|
|
!Context.getLangOpts().SanitizeAddressFieldPadding)
|
2014-10-17 04:54:52 +08:00
|
|
|
return false;
|
2014-10-17 07:50:26 +08:00
|
|
|
const auto &Blacklist = Context.getSanitizerBlacklist();
|
2014-10-17 04:54:52 +08:00
|
|
|
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(this);
|
|
|
|
// We may be able to relax some of these requirements.
|
|
|
|
int ReasonToReject = -1;
|
|
|
|
if (!CXXRD || CXXRD->isExternCContext())
|
|
|
|
ReasonToReject = 0; // is not C++.
|
|
|
|
else if (CXXRD->hasAttr<PackedAttr>())
|
|
|
|
ReasonToReject = 1; // is packed.
|
|
|
|
else if (CXXRD->isUnion())
|
|
|
|
ReasonToReject = 2; // is a union.
|
|
|
|
else if (CXXRD->isTriviallyCopyable())
|
|
|
|
ReasonToReject = 3; // is trivially copyable.
|
|
|
|
else if (CXXRD->hasTrivialDestructor())
|
|
|
|
ReasonToReject = 4; // has trivial destructor.
|
|
|
|
else if (CXXRD->isStandardLayout())
|
|
|
|
ReasonToReject = 5; // is standard layout.
|
2014-10-17 07:50:26 +08:00
|
|
|
else if (Blacklist.isBlacklistedLocation(getLocation(), "field-padding"))
|
2014-10-17 04:54:52 +08:00
|
|
|
ReasonToReject = 6; // is in a blacklisted file.
|
|
|
|
else if (Blacklist.isBlacklistedType(getQualifiedNameAsString(),
|
|
|
|
"field-padding"))
|
|
|
|
ReasonToReject = 7; // is blacklisted.
|
|
|
|
|
|
|
|
if (EmitRemark) {
|
|
|
|
if (ReasonToReject >= 0)
|
|
|
|
Context.getDiagnostics().Report(
|
|
|
|
getLocation(),
|
|
|
|
diag::remark_sanitize_address_insert_extra_padding_rejected)
|
|
|
|
<< getQualifiedNameAsString() << ReasonToReject;
|
|
|
|
else
|
|
|
|
Context.getDiagnostics().Report(
|
|
|
|
getLocation(),
|
|
|
|
diag::remark_sanitize_address_insert_extra_padding_accepted)
|
|
|
|
<< getQualifiedNameAsString();
|
|
|
|
}
|
|
|
|
return ReasonToReject < 0;
|
|
|
|
}
|
|
|
|
|
2014-12-13 00:17:46 +08:00
|
|
|
const FieldDecl *RecordDecl::findFirstNamedDataMember() const {
|
|
|
|
for (const auto *I : fields()) {
|
|
|
|
if (I->getIdentifier())
|
|
|
|
return I;
|
|
|
|
|
|
|
|
if (const RecordType *RT = I->getType()->getAs<RecordType>())
|
|
|
|
if (const FieldDecl *NamedDataMember =
|
|
|
|
RT->getDecl()->findFirstNamedDataMember())
|
|
|
|
return NamedDataMember;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We didn't find a named data member.
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-10-09 01:01:13 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// BlockDecl Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2013-01-13 03:30:44 +08:00
|
|
|
void BlockDecl::setParams(ArrayRef<ParmVarDecl *> NewParamInfo) {
|
2014-05-12 13:36:57 +08:00
|
|
|
assert(!ParamInfo && "Already has param info!");
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-03-14 00:56:44 +08:00
|
|
|
// Zero params -> null pointer.
|
2011-09-22 02:16:56 +08:00
|
|
|
if (!NewParamInfo.empty()) {
|
|
|
|
NumParams = NewParamInfo.size();
|
|
|
|
ParamInfo = new (getASTContext()) ParmVarDecl*[NewParamInfo.size()];
|
|
|
|
std::copy(NewParamInfo.begin(), NewParamInfo.end(), ParamInfo);
|
2009-03-14 00:56:44 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
void BlockDecl::setCaptures(ASTContext &Context,
|
|
|
|
const Capture *begin,
|
|
|
|
const Capture *end,
|
|
|
|
bool capturesCXXThis) {
|
2011-02-02 21:00:07 +08:00
|
|
|
CapturesCXXThis = capturesCXXThis;
|
|
|
|
|
|
|
|
if (begin == end) {
|
2011-02-07 18:33:21 +08:00
|
|
|
NumCaptures = 0;
|
2014-05-12 13:36:57 +08:00
|
|
|
Captures = nullptr;
|
2011-02-02 21:00:07 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
NumCaptures = end - begin;
|
|
|
|
|
|
|
|
// Avoid new Capture[] because we don't want to provide a default
|
|
|
|
// constructor.
|
|
|
|
size_t allocationSize = NumCaptures * sizeof(Capture);
|
|
|
|
void *buffer = Context.Allocate(allocationSize, /*alignment*/sizeof(void*));
|
|
|
|
memcpy(buffer, begin, allocationSize);
|
|
|
|
Captures = static_cast<Capture*>(buffer);
|
2009-03-14 00:56:44 +08:00
|
|
|
}
|
2010-01-27 06:01:41 +08:00
|
|
|
|
2011-06-16 06:51:16 +08:00
|
|
|
bool BlockDecl::capturesVariable(const VarDecl *variable) const {
|
2014-03-15 02:34:04 +08:00
|
|
|
for (const auto &I : captures())
|
2011-06-16 06:51:16 +08:00
|
|
|
// Only auto vars can be captured, so no redeclaration worries.
|
2014-03-15 02:34:04 +08:00
|
|
|
if (I.getVariable() == variable)
|
2011-06-16 06:51:16 +08:00
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-12-22 00:27:07 +08:00
|
|
|
SourceRange BlockDecl::getSourceRange() const {
|
|
|
|
return SourceRange(getLocation(), Body? Body->getLocEnd() : getLocation());
|
|
|
|
}
|
2010-01-27 06:01:41 +08:00
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Other Decl Allocation/Deallocation Method Implementations
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2011-12-20 10:48:34 +08:00
|
|
|
void TranslationUnitDecl::anchor() { }
|
|
|
|
|
2010-01-27 06:01:41 +08:00
|
|
|
TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) {
|
2014-05-12 13:36:57 +08:00
|
|
|
return new (C, (DeclContext *)nullptr) TranslationUnitDecl(C);
|
2010-01-27 06:01:41 +08:00
|
|
|
}
|
|
|
|
|
2015-03-07 08:04:49 +08:00
|
|
|
void ExternCContextDecl::anchor() { }
|
|
|
|
|
|
|
|
ExternCContextDecl *ExternCContextDecl::Create(const ASTContext &C,
|
|
|
|
TranslationUnitDecl *DC) {
|
|
|
|
return new (C, DC) ExternCContextDecl(DC);
|
|
|
|
}
|
|
|
|
|
2011-12-20 10:48:34 +08:00
|
|
|
void LabelDecl::anchor() { }
|
|
|
|
|
2011-02-17 15:39:24 +08:00
|
|
|
LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC,
|
2011-03-06 02:21:20 +08:00
|
|
|
SourceLocation IdentL, IdentifierInfo *II) {
|
2014-05-12 13:36:57 +08:00
|
|
|
return new (C, DC) LabelDecl(DC, IdentL, II, nullptr, IdentL);
|
2011-03-06 02:21:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC,
|
|
|
|
SourceLocation IdentL, IdentifierInfo *II,
|
|
|
|
SourceLocation GnuLabelL) {
|
|
|
|
assert(GnuLabelL != IdentL && "Use this only for GNU local labels");
|
2014-05-12 13:36:57 +08:00
|
|
|
return new (C, DC) LabelDecl(DC, IdentL, II, nullptr, GnuLabelL);
|
2011-02-17 15:39:24 +08:00
|
|
|
}
|
|
|
|
|
2012-01-06 05:55:30 +08:00
|
|
|
LabelDecl *LabelDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
|
2014-05-12 13:36:57 +08:00
|
|
|
return new (C, ID) LabelDecl(nullptr, SourceLocation(), nullptr, nullptr,
|
|
|
|
SourceLocation());
|
2010-10-28 03:49:05 +08:00
|
|
|
}
|
|
|
|
|
2014-09-22 10:21:54 +08:00
|
|
|
void LabelDecl::setMSAsmLabel(StringRef Name) {
|
|
|
|
char *Buffer = new (getASTContext(), 1) char[Name.size() + 1];
|
|
|
|
memcpy(Buffer, Name.data(), Name.size());
|
|
|
|
Buffer[Name.size()] = '\0';
|
|
|
|
MSAsmName = Buffer;
|
|
|
|
}
|
|
|
|
|
2011-12-20 10:48:34 +08:00
|
|
|
void ValueDecl::anchor() { }
|
|
|
|
|
2012-12-01 23:09:41 +08:00
|
|
|
bool ValueDecl::isWeak() const {
|
2014-03-09 06:19:01 +08:00
|
|
|
for (const auto *I : attrs())
|
|
|
|
if (isa<WeakAttr>(I) || isa<WeakRefAttr>(I))
|
2012-12-01 23:09:41 +08:00
|
|
|
return true;
|
|
|
|
|
|
|
|
return isWeakImported();
|
|
|
|
}
|
|
|
|
|
2011-12-20 10:48:34 +08:00
|
|
|
void ImplicitParamDecl::anchor() { }
|
|
|
|
|
2010-01-27 06:01:41 +08:00
|
|
|
ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC,
|
2011-03-08 16:55:46 +08:00
|
|
|
SourceLocation IdLoc,
|
|
|
|
IdentifierInfo *Id,
|
|
|
|
QualType Type) {
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
return new (C, DC) ImplicitParamDecl(C, DC, IdLoc, Id, Type);
|
2010-01-27 06:01:41 +08:00
|
|
|
}
|
|
|
|
|
2013-11-22 17:01:48 +08:00
|
|
|
ImplicitParamDecl *ImplicitParamDecl::CreateDeserialized(ASTContext &C,
|
2012-01-06 05:55:30 +08:00
|
|
|
unsigned ID) {
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
return new (C, ID) ImplicitParamDecl(C, nullptr, SourceLocation(), nullptr,
|
2014-05-12 13:36:57 +08:00
|
|
|
QualType());
|
2012-01-06 05:55:30 +08:00
|
|
|
}
|
|
|
|
|
2010-01-27 06:01:41 +08:00
|
|
|
FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
|
2011-03-08 16:55:46 +08:00
|
|
|
SourceLocation StartLoc,
|
2010-08-12 06:01:17 +08:00
|
|
|
const DeclarationNameInfo &NameInfo,
|
|
|
|
QualType T, TypeSourceInfo *TInfo,
|
2013-04-04 03:27:57 +08:00
|
|
|
StorageClass SC,
|
2013-11-22 17:01:48 +08:00
|
|
|
bool isInlineSpecified,
|
2011-08-16 05:04:07 +08:00
|
|
|
bool hasWrittenPrototype,
|
|
|
|
bool isConstexprSpecified) {
|
2013-11-22 17:01:48 +08:00
|
|
|
FunctionDecl *New =
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
new (C, DC) FunctionDecl(Function, C, DC, StartLoc, NameInfo, T, TInfo,
|
|
|
|
SC, isInlineSpecified, isConstexprSpecified);
|
2010-01-27 06:01:41 +08:00
|
|
|
New->HasWrittenPrototype = hasWrittenPrototype;
|
|
|
|
return New;
|
|
|
|
}
|
|
|
|
|
2012-01-06 05:55:30 +08:00
|
|
|
FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
return new (C, ID) FunctionDecl(Function, C, nullptr, SourceLocation(),
|
2014-05-12 13:36:57 +08:00
|
|
|
DeclarationNameInfo(), QualType(), nullptr,
|
2013-11-22 17:01:48 +08:00
|
|
|
SC_None, false, false);
|
2012-01-06 05:55:30 +08:00
|
|
|
}
|
|
|
|
|
2010-01-27 06:01:41 +08:00
|
|
|
BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {
|
2013-11-22 17:01:48 +08:00
|
|
|
return new (C, DC) BlockDecl(DC, L);
|
2010-01-27 06:01:41 +08:00
|
|
|
}
|
|
|
|
|
2012-01-06 05:55:30 +08:00
|
|
|
BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
|
2014-05-12 13:36:57 +08:00
|
|
|
return new (C, ID) BlockDecl(nullptr, SourceLocation());
|
2013-04-16 15:28:30 +08:00
|
|
|
}
|
|
|
|
|
2013-05-04 03:00:33 +08:00
|
|
|
CapturedDecl *CapturedDecl::Create(ASTContext &C, DeclContext *DC,
|
|
|
|
unsigned NumParams) {
|
2013-11-22 17:01:48 +08:00
|
|
|
return new (C, DC, NumParams * sizeof(ImplicitParamDecl *))
|
|
|
|
CapturedDecl(DC, NumParams);
|
2013-04-17 03:37:38 +08:00
|
|
|
}
|
|
|
|
|
2013-05-04 03:20:19 +08:00
|
|
|
CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, unsigned ID,
|
2013-11-22 17:01:48 +08:00
|
|
|
unsigned NumParams) {
|
|
|
|
return new (C, ID, NumParams * sizeof(ImplicitParamDecl *))
|
2014-05-12 13:36:57 +08:00
|
|
|
CapturedDecl(nullptr, NumParams);
|
2013-05-04 03:20:19 +08:00
|
|
|
}
|
|
|
|
|
2010-01-27 06:01:41 +08:00
|
|
|
EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
|
|
|
|
SourceLocation L,
|
|
|
|
IdentifierInfo *Id, QualType T,
|
|
|
|
Expr *E, const llvm::APSInt &V) {
|
2013-11-22 17:01:48 +08:00
|
|
|
return new (C, CD) EnumConstantDecl(CD, L, Id, T, E, V);
|
2010-01-27 06:01:41 +08:00
|
|
|
}
|
|
|
|
|
2012-01-06 05:55:30 +08:00
|
|
|
EnumConstantDecl *
|
|
|
|
EnumConstantDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
|
2014-05-12 13:36:57 +08:00
|
|
|
return new (C, ID) EnumConstantDecl(nullptr, SourceLocation(), nullptr,
|
|
|
|
QualType(), nullptr, llvm::APSInt());
|
2012-01-06 05:55:30 +08:00
|
|
|
}
|
|
|
|
|
2011-12-20 10:48:34 +08:00
|
|
|
void IndirectFieldDecl::anchor() { }
|
|
|
|
|
2010-11-21 22:11:41 +08:00
|
|
|
IndirectFieldDecl *
|
|
|
|
IndirectFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
|
|
|
|
IdentifierInfo *Id, QualType T, NamedDecl **CH,
|
|
|
|
unsigned CHS) {
|
2013-11-22 17:01:48 +08:00
|
|
|
return new (C, DC) IndirectFieldDecl(DC, L, Id, T, CH, CHS);
|
2010-11-21 14:08:52 +08:00
|
|
|
}
|
|
|
|
|
2012-01-06 05:55:30 +08:00
|
|
|
IndirectFieldDecl *IndirectFieldDecl::CreateDeserialized(ASTContext &C,
|
|
|
|
unsigned ID) {
|
2014-05-12 13:36:57 +08:00
|
|
|
return new (C, ID) IndirectFieldDecl(nullptr, SourceLocation(),
|
|
|
|
DeclarationName(), QualType(), nullptr,
|
|
|
|
0);
|
2012-01-06 05:55:30 +08:00
|
|
|
}
|
|
|
|
|
2010-09-02 04:41:53 +08:00
|
|
|
SourceRange EnumConstantDecl::getSourceRange() const {
|
|
|
|
SourceLocation End = getLocation();
|
|
|
|
if (Init)
|
|
|
|
End = Init->getLocEnd();
|
|
|
|
return SourceRange(getLocation(), End);
|
|
|
|
}
|
|
|
|
|
2011-12-20 10:48:34 +08:00
|
|
|
void TypeDecl::anchor() { }
|
|
|
|
|
2010-01-27 06:01:41 +08:00
|
|
|
TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
|
2011-03-06 23:48:19 +08:00
|
|
|
SourceLocation StartLoc, SourceLocation IdLoc,
|
|
|
|
IdentifierInfo *Id, TypeSourceInfo *TInfo) {
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
return new (C, DC) TypedefDecl(C, DC, StartLoc, IdLoc, Id, TInfo);
|
2010-01-27 06:01:41 +08:00
|
|
|
}
|
|
|
|
|
2011-12-20 10:48:34 +08:00
|
|
|
void TypedefNameDecl::anchor() { }
|
|
|
|
|
2015-03-27 09:37:43 +08:00
|
|
|
TagDecl *TypedefNameDecl::getAnonDeclWithTypedefName() const {
|
|
|
|
if (auto *TT = getTypeSourceInfo()->getType()->getAs<TagType>())
|
|
|
|
if (TT->getDecl()->getTypedefNameForAnonDecl() == this)
|
|
|
|
return TT->getDecl();
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2012-01-06 05:55:30 +08:00
|
|
|
TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
return new (C, ID) TypedefDecl(C, nullptr, SourceLocation(), SourceLocation(),
|
2014-05-12 13:36:57 +08:00
|
|
|
nullptr, nullptr);
|
2012-01-06 05:55:30 +08:00
|
|
|
}
|
|
|
|
|
2011-04-15 22:24:37 +08:00
|
|
|
TypeAliasDecl *TypeAliasDecl::Create(ASTContext &C, DeclContext *DC,
|
|
|
|
SourceLocation StartLoc,
|
|
|
|
SourceLocation IdLoc, IdentifierInfo *Id,
|
|
|
|
TypeSourceInfo *TInfo) {
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
return new (C, DC) TypeAliasDecl(C, DC, StartLoc, IdLoc, Id, TInfo);
|
2011-04-15 22:24:37 +08:00
|
|
|
}
|
|
|
|
|
2012-01-06 05:55:30 +08:00
|
|
|
TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
return new (C, ID) TypeAliasDecl(C, nullptr, SourceLocation(),
|
|
|
|
SourceLocation(), nullptr, nullptr);
|
2012-01-06 05:55:30 +08:00
|
|
|
}
|
|
|
|
|
2011-03-09 00:41:52 +08:00
|
|
|
SourceRange TypedefDecl::getSourceRange() const {
|
|
|
|
SourceLocation RangeEnd = getLocation();
|
|
|
|
if (TypeSourceInfo *TInfo = getTypeSourceInfo()) {
|
|
|
|
if (typeIsPostfix(TInfo->getType()))
|
|
|
|
RangeEnd = TInfo->getTypeLoc().getSourceRange().getEnd();
|
|
|
|
}
|
|
|
|
return SourceRange(getLocStart(), RangeEnd);
|
|
|
|
}
|
|
|
|
|
2011-04-15 22:24:37 +08:00
|
|
|
SourceRange TypeAliasDecl::getSourceRange() const {
|
|
|
|
SourceLocation RangeEnd = getLocStart();
|
|
|
|
if (TypeSourceInfo *TInfo = getTypeSourceInfo())
|
|
|
|
RangeEnd = TInfo->getTypeLoc().getSourceRange().getEnd();
|
|
|
|
return SourceRange(getLocStart(), RangeEnd);
|
|
|
|
}
|
|
|
|
|
2011-12-20 10:48:34 +08:00
|
|
|
void FileScopeAsmDecl::anchor() { }
|
|
|
|
|
2010-01-27 06:01:41 +08:00
|
|
|
FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC,
|
2011-03-03 22:20:18 +08:00
|
|
|
StringLiteral *Str,
|
|
|
|
SourceLocation AsmLoc,
|
|
|
|
SourceLocation RParenLoc) {
|
2013-11-22 17:01:48 +08:00
|
|
|
return new (C, DC) FileScopeAsmDecl(DC, Str, AsmLoc, RParenLoc);
|
2010-01-27 06:01:41 +08:00
|
|
|
}
|
2011-12-03 07:23:56 +08:00
|
|
|
|
2013-11-22 17:01:48 +08:00
|
|
|
FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C,
|
2012-01-06 05:55:30 +08:00
|
|
|
unsigned ID) {
|
2014-05-12 13:36:57 +08:00
|
|
|
return new (C, ID) FileScopeAsmDecl(nullptr, nullptr, SourceLocation(),
|
|
|
|
SourceLocation());
|
2012-01-06 05:55:30 +08:00
|
|
|
}
|
|
|
|
|
2013-02-23 01:15:32 +08:00
|
|
|
void EmptyDecl::anchor() {}
|
|
|
|
|
|
|
|
EmptyDecl *EmptyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {
|
2013-11-22 17:01:48 +08:00
|
|
|
return new (C, DC) EmptyDecl(DC, L);
|
2013-02-23 01:15:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
|
2014-05-12 13:36:57 +08:00
|
|
|
return new (C, ID) EmptyDecl(nullptr, SourceLocation());
|
2013-02-23 01:15:32 +08:00
|
|
|
}
|
|
|
|
|
2011-12-03 07:23:56 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// ImportDecl Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// \brief Retrieve the number of module identifiers needed to name the given
|
|
|
|
/// module.
|
|
|
|
static unsigned getNumModuleIdentifiers(Module *Mod) {
|
|
|
|
unsigned Result = 1;
|
|
|
|
while (Mod->Parent) {
|
|
|
|
Mod = Mod->Parent;
|
|
|
|
++Result;
|
|
|
|
}
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2012-01-04 02:04:46 +08:00
|
|
|
ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc,
|
2011-12-03 07:23:56 +08:00
|
|
|
Module *Imported,
|
|
|
|
ArrayRef<SourceLocation> IdentifierLocs)
|
2012-01-04 02:04:46 +08:00
|
|
|
: Decl(Import, DC, StartLoc), ImportedAndComplete(Imported, true),
|
2011-12-03 08:30:27 +08:00
|
|
|
NextLocalImport()
|
2011-12-03 07:23:56 +08:00
|
|
|
{
|
|
|
|
assert(getNumModuleIdentifiers(Imported) == IdentifierLocs.size());
|
|
|
|
SourceLocation *StoredLocs = reinterpret_cast<SourceLocation *>(this + 1);
|
|
|
|
memcpy(StoredLocs, IdentifierLocs.data(),
|
|
|
|
IdentifierLocs.size() * sizeof(SourceLocation));
|
|
|
|
}
|
|
|
|
|
2012-01-04 02:04:46 +08:00
|
|
|
ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc,
|
2011-12-03 07:23:56 +08:00
|
|
|
Module *Imported, SourceLocation EndLoc)
|
2012-01-04 02:04:46 +08:00
|
|
|
: Decl(Import, DC, StartLoc), ImportedAndComplete(Imported, false),
|
2011-12-03 08:30:27 +08:00
|
|
|
NextLocalImport()
|
2011-12-03 07:23:56 +08:00
|
|
|
{
|
|
|
|
*reinterpret_cast<SourceLocation *>(this + 1) = EndLoc;
|
|
|
|
}
|
|
|
|
|
2013-11-22 17:01:48 +08:00
|
|
|
ImportDecl *ImportDecl::Create(ASTContext &C, DeclContext *DC,
|
2012-01-04 02:04:46 +08:00
|
|
|
SourceLocation StartLoc, Module *Imported,
|
2011-12-03 07:23:56 +08:00
|
|
|
ArrayRef<SourceLocation> IdentifierLocs) {
|
2013-11-22 17:01:48 +08:00
|
|
|
return new (C, DC, IdentifierLocs.size() * sizeof(SourceLocation))
|
|
|
|
ImportDecl(DC, StartLoc, Imported, IdentifierLocs);
|
2011-12-03 07:23:56 +08:00
|
|
|
}
|
|
|
|
|
2013-11-22 17:01:48 +08:00
|
|
|
ImportDecl *ImportDecl::CreateImplicit(ASTContext &C, DeclContext *DC,
|
2012-01-04 02:04:46 +08:00
|
|
|
SourceLocation StartLoc,
|
2013-11-22 17:01:48 +08:00
|
|
|
Module *Imported,
|
2011-12-03 07:23:56 +08:00
|
|
|
SourceLocation EndLoc) {
|
2013-11-22 17:01:48 +08:00
|
|
|
ImportDecl *Import =
|
|
|
|
new (C, DC, sizeof(SourceLocation)) ImportDecl(DC, StartLoc,
|
|
|
|
Imported, EndLoc);
|
2011-12-03 07:23:56 +08:00
|
|
|
Import->setImplicit();
|
|
|
|
return Import;
|
|
|
|
}
|
|
|
|
|
2012-01-06 05:55:30 +08:00
|
|
|
ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, unsigned ID,
|
|
|
|
unsigned NumLocations) {
|
2013-11-22 17:01:48 +08:00
|
|
|
return new (C, ID, NumLocations * sizeof(SourceLocation))
|
|
|
|
ImportDecl(EmptyShell());
|
2011-12-03 07:23:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
ArrayRef<SourceLocation> ImportDecl::getIdentifierLocs() const {
|
|
|
|
if (!ImportedAndComplete.getInt())
|
2013-05-05 08:41:58 +08:00
|
|
|
return None;
|
2011-12-03 07:23:56 +08:00
|
|
|
|
|
|
|
const SourceLocation *StoredLocs
|
|
|
|
= reinterpret_cast<const SourceLocation *>(this + 1);
|
2014-08-27 14:28:36 +08:00
|
|
|
return llvm::makeArrayRef(StoredLocs,
|
|
|
|
getNumModuleIdentifiers(getImportedModule()));
|
2011-12-03 07:23:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SourceRange ImportDecl::getSourceRange() const {
|
|
|
|
if (!ImportedAndComplete.getInt())
|
|
|
|
return SourceRange(getLocation(),
|
|
|
|
*reinterpret_cast<const SourceLocation *>(this + 1));
|
|
|
|
|
|
|
|
return SourceRange(getLocation(), getIdentifierLocs().back());
|
|
|
|
}
|