aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Decl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-03-02 00:19:53 +0000
committerDouglas Gregor <dgregor@apple.com>2009-03-02 00:19:53 +0000
commit6393519272ce727f4d26e71bbefb5de712274d0e (patch)
tree1ebe5d1a23ac06f5fadd2152adff7bf0740dc3f0 /lib/AST/Decl.cpp
parent8045ee072879657370cbd97dca46aea45ec44e2d (diff)
Rework the way we find locally-scoped external declarations when we
need them to evaluate redeclarations or call a function that hasn't already been declared. We now keep a DenseMap of these locally-scoped declarations so that they are not visible but can be quickly found, e.g., when we're looking for previous declarations or before we go ahead and implicitly declare a function that's being called. Fixes PR3672. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65792 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r--lib/AST/Decl.cpp41
1 files changed, 41 insertions, 0 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index b30b86980f..1ebfbf79da 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -63,6 +63,28 @@ QualType ParmVarDecl::getOriginalType() const {
return getType();
}
+bool VarDecl::isExternC(ASTContext &Context) const {
+ if (!Context.getLangOptions().CPlusPlus)
+ return (getDeclContext()->isTranslationUnit() &&
+ getStorageClass() != Static) ||
+ (getDeclContext()->isFunctionOrMethod() && hasExternalStorage());
+
+ for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit();
+ DC = DC->getParent()) {
+ if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) {
+ if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
+ return getStorageClass() != Static;
+
+ break;
+ }
+
+ if (DC->isFunctionOrMethod())
+ return false;
+ }
+
+ return false;
+}
+
OriginalParmVarDecl *OriginalParmVarDecl::Create(
ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
@@ -273,6 +295,25 @@ bool FunctionDecl::isMain() const {
getIdentifier() && getIdentifier()->isStr("main");
}
+bool FunctionDecl::isExternC(ASTContext &Context) const {
+ // In C, any non-static, non-overloadable function has external
+ // linkage.
+ if (!Context.getLangOptions().CPlusPlus)
+ return getStorageClass() != Static && !getAttr<OverloadableAttr>();
+
+ for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit();
+ DC = DC->getParent()) {
+ if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) {
+ if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
+ return getStorageClass() != Static && !getAttr<OverloadableAttr>();
+
+ break;
+ }
+ }
+
+ return false;
+}
+
/// \brief Returns a value indicating whether this function
/// corresponds to a builtin function.
///