diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-05-05 20:15:21 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-05-05 20:15:21 +0000 |
commit | d8ffd0b7b61566f15a67192883a607f7703bcece (patch) | |
tree | 1589b51840a6db685aa0913ea7c019eef0f47e36 /lib/AST | |
parent | 287f24d3991994b9a263af9e2a873f4feadfb8fa (diff) |
Make all 'is in extern "C"' tests use the lexical context.
I was not able to find a case (other than the fix in r181163) where this
makes a difference, but it is a more obviously correct API to have.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181165 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/Decl.cpp | 51 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 22 |
2 files changed, 40 insertions, 33 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index ff012fc401..ab9d73b917 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -471,9 +471,9 @@ 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) { @@ -548,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(); } @@ -626,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(); @@ -660,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(); @@ -997,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. @@ -1020,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; @@ -1522,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; } @@ -1549,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(); } @@ -2070,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(); diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 7b7900640b..084a4321d8 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -819,28 +819,6 @@ bool DeclContext::isTransparentContext() const { return false; } -bool DeclContext::isExternCContext() const { - const DeclContext *DC = this; - while (DC->DeclKind != Decl::TranslationUnit) { - if (DC->DeclKind == Decl::LinkageSpec) - return cast<LinkageSpecDecl>(DC)->getLanguage() - == LinkageSpecDecl::lang_c; - DC = DC->getParent(); - } - return false; -} - -bool DeclContext::isExternCXXContext() const { - const DeclContext *DC = this; - while (DC->DeclKind != Decl::TranslationUnit) { - if (DC->DeclKind == Decl::LinkageSpec) - return cast<LinkageSpecDecl>(DC)->getLanguage() - == LinkageSpecDecl::lang_cxx; - DC = DC->getParent(); - } - return false; -} - bool DeclContext::Encloses(const DeclContext *DC) const { if (getPrimaryContext() != this) return getPrimaryContext()->Encloses(DC); |