summaryrefslogtreecommitdiffstats
path: root/lib/AST/Decl.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2013-06-10 20:45:12 +0000
committerdim <dim@FreeBSD.org>2013-06-10 20:45:12 +0000
commitea266cad53e3d49771fa38103913d3ec7a166694 (patch)
tree8f7776b7310bebaf415ac5b69e46e9f928c37144 /lib/AST/Decl.cpp
parentc72c57c9e9b69944e3e009cd5e209634839581d3 (diff)
downloadFreeBSD-src-ea266cad53e3d49771fa38103913d3ec7a166694.zip
FreeBSD-src-ea266cad53e3d49771fa38103913d3ec7a166694.tar.gz
Vendor import of clang tags/RELEASE_33/final r183502 (effectively, 3.3
release): http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_33/final@183502
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r--lib/AST/Decl.cpp111
1 files changed, 85 insertions, 26 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index bf807ae..ab9d73b 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -471,9 +471,16 @@ static bool useInlineVisibilityHidden(const NamedDecl *D) {
FD->hasBody(Def) && Def->isInlined() && !Def->hasAttr<GNUInlineAttr>();
}
-template <typename T> static bool isInExternCContext(T *D) {
+template <typename T> static bool isFirstInExternCContext(T *D) {
const T *First = D->getFirstDeclaration();
- return First->getDeclContext()->isExternCContext();
+ return First->isInExternCContext();
+}
+
+static bool isSingleLineExternC(const Decl &D) {
+ if (const LinkageSpecDecl *SD = dyn_cast<LinkageSpecDecl>(D.getDeclContext()))
+ if (SD->getLanguage() == LinkageSpecDecl::lang_c && !SD->hasBraces())
+ return true;
+ return false;
}
static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
@@ -504,7 +511,8 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
return PrevVar->getLinkageAndVisibility();
if (Var->getStorageClass() != SC_Extern &&
- Var->getStorageClass() != SC_PrivateExtern)
+ Var->getStorageClass() != SC_PrivateExtern &&
+ !isSingleLineExternC(*Var))
return LinkageInfo::internal();
}
@@ -540,8 +548,8 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
if (D->isInAnonymousNamespace()) {
const VarDecl *Var = dyn_cast<VarDecl>(D);
const FunctionDecl *Func = dyn_cast<FunctionDecl>(D);
- if ((!Var || !isInExternCContext(Var)) &&
- (!Func || !isInExternCContext(Func)))
+ if ((!Var || !isFirstInExternCContext(Var)) &&
+ (!Func || !isFirstInExternCContext(Func)))
return LinkageInfo::uniqueExternal();
}
@@ -618,7 +626,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
//
// Note that we don't want to make the variable non-external
// because of this, but unique-external linkage suits us.
- if (Context.getLangOpts().CPlusPlus && !isInExternCContext(Var)) {
+ if (Context.getLangOpts().CPlusPlus && !isFirstInExternCContext(Var)) {
LinkageInfo TypeLV = Var->getType()->getLinkageAndVisibility();
if (TypeLV.getLinkage() != ExternalLinkage)
return LinkageInfo::uniqueExternal();
@@ -652,7 +660,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// this translation unit. However, we should use the C linkage
// rules instead for extern "C" declarations.
if (Context.getLangOpts().CPlusPlus &&
- !Function->getDeclContext()->isExternCContext() &&
+ !Function->isInExternCContext() &&
Function->getType()->getLinkage() == UniqueExternalLinkage)
return LinkageInfo::uniqueExternal();
@@ -866,10 +874,6 @@ bool NamedDecl::isLinkageValid() const {
Linkage(CachedLinkage);
}
-bool NamedDecl::hasExternalLinkageUncached() const {
- return getLVForDecl(this, LVForExplicitValue).getLinkage() == ExternalLinkage;
-}
-
Linkage NamedDecl::getLinkage() const {
if (HasCachedLinkage)
return Linkage(CachedLinkage);
@@ -993,7 +997,7 @@ static LinkageInfo getLVForLocalDecl(const NamedDecl *D,
LVComputationKind computation) {
if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
if (Function->isInAnonymousNamespace() &&
- !Function->getDeclContext()->isExternCContext())
+ !Function->isInExternCContext())
return LinkageInfo::uniqueExternal();
// This is a "void f();" which got merged with a file static.
@@ -1016,8 +1020,7 @@ static LinkageInfo getLVForLocalDecl(const NamedDecl *D,
if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
if (Var->hasExternalStorage()) {
- if (Var->isInAnonymousNamespace() &&
- !Var->getDeclContext()->isExternCContext())
+ if (Var->isInAnonymousNamespace() && !Var->isInExternCContext())
return LinkageInfo::uniqueExternal();
LinkageInfo LV;
@@ -1297,7 +1300,7 @@ bool NamedDecl::isCXXInstanceMember() const {
if (isa<UsingShadowDecl>(D))
D = cast<UsingShadowDecl>(D)->getTargetDecl();
- if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D))
+ if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D) || isa<MSPropertyDecl>(D))
return true;
if (isa<CXXMethodDecl>(D))
return cast<CXXMethodDecl>(D)->isInstance();
@@ -1518,8 +1521,7 @@ static LanguageLinkage getLanguageLinkageTemplate(const T &D) {
// 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.
- const T *First = D.getFirstDeclaration();
- if (First->getDeclContext()->isExternCContext())
+ if (isFirstInExternCContext(&D))
return CLanguageLinkage;
return CXXLanguageLinkage;
}
@@ -1545,6 +1547,29 @@ bool VarDecl::isExternC() const {
return isExternCTemplate(*this);
}
+static bool isLinkageSpecContext(const DeclContext *DC,
+ LinkageSpecDecl::LanguageIDs ID) {
+ while (DC->getDeclKind() != Decl::TranslationUnit) {
+ if (DC->getDeclKind() == Decl::LinkageSpec)
+ return cast<LinkageSpecDecl>(DC)->getLanguage() == ID;
+ DC = DC->getParent();
+ }
+ return false;
+}
+
+template <typename T>
+static bool isInLanguageSpecContext(T *D, LinkageSpecDecl::LanguageIDs ID) {
+ return isLinkageSpecContext(D->getLexicalDeclContext(), ID);
+}
+
+bool VarDecl::isInExternCContext() const {
+ return isInLanguageSpecContext(this, LinkageSpecDecl::lang_c);
+}
+
+bool VarDecl::isInExternCXXContext() const {
+ return isInLanguageSpecContext(this, LinkageSpecDecl::lang_cxx);
+}
+
VarDecl *VarDecl::getCanonicalDecl() {
return getFirstDeclaration();
}
@@ -1576,17 +1601,17 @@ VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition(
// initializer, the declaration is an external definition for the identifier
if (hasInit())
return Definition;
- // AST for 'extern "C" int foo;' is annotated with 'extern'.
+
if (hasExternalStorage())
return DeclarationOnly;
- if (hasExternalStorage()) {
- for (const VarDecl *PrevVar = getPreviousDecl();
- PrevVar; PrevVar = PrevVar->getPreviousDecl()) {
- if (PrevVar->getLinkage() == InternalLinkage)
- return DeclarationOnly;
- }
- }
+ // [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.
+ if (isSingleLineExternC(*this))
+ return DeclarationOnly;
+
// 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
@@ -1896,6 +1921,11 @@ SourceRange ParmVarDecl::getSourceRange() const {
return SourceRange(getOuterLocStart(), ArgRange.getEnd());
}
+ // 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());
+
return DeclaratorDecl::getSourceRange();
}
@@ -2061,6 +2091,14 @@ bool FunctionDecl::isExternC() const {
return isExternCTemplate(*this);
}
+bool FunctionDecl::isInExternCContext() const {
+ return isInLanguageSpecContext(this, LinkageSpecDecl::lang_c);
+}
+
+bool FunctionDecl::isInExternCXXContext() const {
+ return isInLanguageSpecContext(this, LinkageSpecDecl::lang_cxx);
+}
+
bool FunctionDecl::isGlobal() const {
if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(this))
return Method->isStatic();
@@ -3230,6 +3268,27 @@ BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
return new (Mem) BlockDecl(0, SourceLocation());
}
+MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C,
+ unsigned ID) {
+ void *Mem = AllocateDeserializedDecl(C, ID, sizeof(MSPropertyDecl));
+ return new (Mem) MSPropertyDecl(0, SourceLocation(), DeclarationName(),
+ QualType(), 0, SourceLocation(),
+ 0, 0);
+}
+
+CapturedDecl *CapturedDecl::Create(ASTContext &C, DeclContext *DC,
+ unsigned NumParams) {
+ unsigned Size = sizeof(CapturedDecl) + NumParams * sizeof(ImplicitParamDecl*);
+ return new (C.Allocate(Size)) CapturedDecl(DC, NumParams);
+}
+
+CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, unsigned ID,
+ unsigned NumParams) {
+ unsigned Size = sizeof(CapturedDecl) + NumParams * sizeof(ImplicitParamDecl*);
+ void *Mem = AllocateDeserializedDecl(C, ID, Size);
+ return new (Mem) CapturedDecl(0, NumParams);
+}
+
EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
SourceLocation L,
IdentifierInfo *Id, QualType T,
@@ -3399,7 +3458,7 @@ ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, unsigned ID,
ArrayRef<SourceLocation> ImportDecl::getIdentifierLocs() const {
if (!ImportedAndComplete.getInt())
- return ArrayRef<SourceLocation>();
+ return None;
const SourceLocation *StoredLocs
= reinterpret_cast<const SourceLocation *>(this + 1);
OpenPOWER on IntegriCloud