aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2010-07-27 22:37:14 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2010-07-27 22:37:14 +0000
commita6d6af308bfc9b72467b432a045a9fc6673e3821 (patch)
tree79b6e5400e07ebd01988d1fe0f6a228608b95826
parentee94e2d10728d1b6a87a11aeee122e8759f58c63 (diff)
Revert r109546, it broke linux build.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109550 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/CodeGen/BackendUtil.h9
-rw-r--r--lib/CodeGen/CodeGenModule.cpp98
-rw-r--r--lib/Frontend/PCHWriterDecl.cpp54
-rw-r--r--test/PCH/cxx-required-decls.cpp1
-rw-r--r--test/PCH/cxx-required-decls.h3
-rw-r--r--tools/libclang/Makefile2
6 files changed, 91 insertions, 76 deletions
diff --git a/include/clang/CodeGen/BackendUtil.h b/include/clang/CodeGen/BackendUtil.h
index 193a0fb4d9..abcef8130d 100644
--- a/include/clang/CodeGen/BackendUtil.h
+++ b/include/clang/CodeGen/BackendUtil.h
@@ -19,7 +19,6 @@ namespace clang {
class Diagnostic;
class CodeGenOptions;
class TargetOptions;
- class Decl;
enum BackendAction {
Backend_EmitAssembly, ///< Emit native assembly files
@@ -33,14 +32,6 @@ namespace clang {
void EmitBackendOutput(Diagnostic &Diags, const CodeGenOptions &CGOpts,
const TargetOptions &TOpts, llvm::Module *M,
BackendAction Action, llvm::raw_ostream *OS);
-
- /// \brief Determines if the decl can be CodeGen'ed or deserialized from PCH
- /// lazily, only when used; this is only relevant for function or file scoped
- /// var definitions.
- ///
- /// \returns true if the function/var must be CodeGen'ed/deserialized even if
- /// it is not used.
- bool DeclIsRequiredFunctionOrFileScopedVar(const Decl *D);
}
#endif
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index a574bb6a98..057182d039 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -18,7 +18,6 @@
#include "CGObjCRuntime.h"
#include "Mangle.h"
#include "TargetInfo.h"
-#include "clang/CodeGen/BackendUtil.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CharUnits.h"
@@ -324,11 +323,12 @@ void CodeGenModule::EmitAnnotations() {
}
static CodeGenModule::GVALinkage
-GetLinkageForFunction(const FunctionDecl *FD, const LangOptions &Features) {
+GetLinkageForFunction(ASTContext &Context, const FunctionDecl *FD,
+ const LangOptions &Features) {
CodeGenModule::GVALinkage External = CodeGenModule::GVA_StrongExternal;
Linkage L = FD->getLinkage();
- if (L == ExternalLinkage && Features.CPlusPlus &&
+ if (L == ExternalLinkage && Context.getLangOptions().CPlusPlus &&
FD->getType()->getLinkage() == UniqueExternalLinkage)
L = UniqueExternalLinkage;
@@ -383,7 +383,7 @@ GetLinkageForFunction(const FunctionDecl *FD, const LangOptions &Features) {
llvm::GlobalValue::LinkageTypes
CodeGenModule::getFunctionLinkage(const FunctionDecl *D) {
- GVALinkage Linkage = GetLinkageForFunction(D, Features);
+ GVALinkage Linkage = GetLinkageForFunction(getContext(), D, Features);
if (Linkage == GVA_Internal)
return llvm::Function::InternalLinkage;
@@ -642,7 +642,7 @@ llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV,
}
static CodeGenModule::GVALinkage
-GetLinkageForVariable(const VarDecl *VD, const LangOptions &Features) {
+GetLinkageForVariable(ASTContext &Context, const VarDecl *VD) {
// If this is a static data member, compute the kind of template
// specialization. Otherwise, this variable is not part of a
// template.
@@ -651,7 +651,7 @@ GetLinkageForVariable(const VarDecl *VD, const LangOptions &Features) {
TSK = VD->getTemplateSpecializationKind();
Linkage L = VD->getLinkage();
- if (L == ExternalLinkage && Features.CPlusPlus &&
+ if (L == ExternalLinkage && Context.getLangOptions().CPlusPlus &&
VD->getType()->getLinkage() == UniqueExternalLinkage)
L = UniqueExternalLinkage;
@@ -682,83 +682,61 @@ GetLinkageForVariable(const VarDecl *VD, const LangOptions &Features) {
return CodeGenModule::GVA_StrongExternal;
}
-bool clang::DeclIsRequiredFunctionOrFileScopedVar(const Decl *D) {
- if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
- if (!VD->isFileVarDecl())
- return false;
- } else if (!isa<FunctionDecl>(D))
+bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
+ // Never defer when EmitAllDecls is specified or the decl has
+ // attribute used.
+ if (Features.EmitAllDecls || Global->hasAttr<UsedAttr>())
return false;
- // Aliases and used decls are required.
- if (D->hasAttr<AliasAttr>() || D->hasAttr<UsedAttr>())
- return true;
-
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- // Forward declarations aren't required.
- if (!FD->isThisDeclarationADefinition())
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) {
+ // Constructors and destructors should never be deferred.
+ if (FD->hasAttr<ConstructorAttr>() ||
+ FD->hasAttr<DestructorAttr>())
return false;
- // Constructors and destructors are required.
- if (FD->hasAttr<ConstructorAttr>() || FD->hasAttr<DestructorAttr>())
- return true;
-
- ASTContext &Ctx = FD->getASTContext();
-
- // The key function for a class is required.
- if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+ // The key function for a class must never be deferred.
+ if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Global)) {
const CXXRecordDecl *RD = MD->getParent();
if (MD->isOutOfLine() && RD->isDynamicClass()) {
- const CXXMethodDecl *KeyFunc = Ctx.getKeyFunction(RD);
- if (KeyFunc && KeyFunc->getCanonicalDecl() == MD->getCanonicalDecl())
- return true;
+ const CXXMethodDecl *KeyFunction = getContext().getKeyFunction(RD);
+ if (KeyFunction &&
+ KeyFunction->getCanonicalDecl() == MD->getCanonicalDecl())
+ return false;
}
}
- CodeGenModule::GVALinkage Linkage
- = GetLinkageForFunction(FD, Ctx.getLangOptions());
+ GVALinkage Linkage = GetLinkageForFunction(getContext(), FD, Features);
// static, static inline, always_inline, and extern inline functions can
// always be deferred. Normal inline functions can be deferred in C99/C++.
// Implicit template instantiations can also be deferred in C++.
- if (Linkage == CodeGenModule::GVA_Internal ||
- Linkage == CodeGenModule::GVA_C99Inline ||
- Linkage == CodeGenModule::GVA_CXXInline ||
- Linkage == CodeGenModule::GVA_TemplateInstantiation)
- return false;
- return true;
+ if (Linkage == GVA_Internal || Linkage == GVA_C99Inline ||
+ Linkage == GVA_CXXInline || Linkage == GVA_TemplateInstantiation)
+ return true;
+ return false;
}
- const VarDecl *VD = cast<VarDecl>(D);
- assert(VD->isFileVarDecl() && "Expected file scoped var");
-
- // Structs that have non-trivial constructors or destructors are required.
+ const VarDecl *VD = cast<VarDecl>(Global);
+ assert(VD->isFileVarDecl() && "Invalid decl");
+ // We never want to defer structs that have non-trivial constructors or
+ // destructors.
+
// FIXME: Handle references.
if (const RecordType *RT = VD->getType()->getAs<RecordType>()) {
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
if (!RD->hasTrivialConstructor() || !RD->hasTrivialDestructor())
- return true;
+ return false;
}
}
-
- ASTContext &Ctx = VD->getASTContext();
-
- CodeGenModule::GVALinkage L = GetLinkageForVariable(VD, Ctx.getLangOptions());
- if (L == CodeGenModule::GVA_Internal ||
- L == CodeGenModule::GVA_TemplateInstantiation) {
- if (!(VD->getInit() && VD->getInit()->HasSideEffects(Ctx)))
- return false;
+
+ GVALinkage L = GetLinkageForVariable(getContext(), VD);
+ if (L == GVA_Internal || L == GVA_TemplateInstantiation) {
+ if (!(VD->getInit() && VD->getInit()->HasSideEffects(Context)))
+ return true;
}
- return true;
-}
-
-bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
- // Never defer when EmitAllDecls is specified.
- if (Features.EmitAllDecls)
- return false;
-
- return !DeclIsRequiredFunctionOrFileScopedVar(Global);
+ return false;
}
llvm::Constant *CodeGenModule::GetWeakRefReference(const ValueDecl *VD) {
@@ -1293,7 +1271,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
GV->setAlignment(getContext().getDeclAlign(D).getQuantity());
// Set the llvm linkage type as appropriate.
- GVALinkage Linkage = GetLinkageForVariable(D, Features);
+ GVALinkage Linkage = GetLinkageForVariable(getContext(), D);
if (Linkage == GVA_Internal)
GV->setLinkage(llvm::Function::InternalLinkage);
else if (D->hasAttr<DLLImportAttr>())
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp
index f0d563297b..06266d2282 100644
--- a/lib/Frontend/PCHWriterDecl.cpp
+++ b/lib/Frontend/PCHWriterDecl.cpp
@@ -16,7 +16,6 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
-#include "clang/CodeGen/BackendUtil.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Bitcode/BitstreamWriter.h"
#include "llvm/Support/ErrorHandling.h"
@@ -1079,12 +1078,63 @@ void PCHWriter::WriteDeclsBlockAbbrevs() {
/// clients to use a separate API call to "realize" the decl. This should be
/// relatively painless since they would presumably only do it for top-level
/// decls.
+//
+// FIXME: This predicate is essentially IRgen's predicate to determine whether a
+// declaration can be deferred. Merge them somehow.
static bool isRequiredDecl(const Decl *D, ASTContext &Context) {
// File scoped assembly must be seen.
if (isa<FileScopeAsmDecl>(D))
return true;
- return DeclIsRequiredFunctionOrFileScopedVar(D);
+ // Otherwise if this isn't a function or a file scoped variable it doesn't
+ // need to be seen.
+ if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (!VD->isFileVarDecl())
+ return false;
+ } else if (!isa<FunctionDecl>(D))
+ return false;
+
+ // Aliases and used decls must be seen.
+ if (D->hasAttr<AliasAttr>() || D->hasAttr<UsedAttr>())
+ return true;
+
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ // Forward declarations don't need to be seen.
+ if (!FD->isThisDeclarationADefinition())
+ return false;
+
+ // Constructors and destructors must be seen.
+ if (FD->hasAttr<ConstructorAttr>() || FD->hasAttr<DestructorAttr>())
+ return true;
+
+ // Otherwise, this is required unless it is static.
+ //
+ // FIXME: Inlines.
+ return FD->getStorageClass() != FunctionDecl::Static;
+ } else {
+ const VarDecl *VD = cast<VarDecl>(D);
+
+ // Structs that have non-trivial constructors or destructors must be seen.
+ if (const RecordType *RT = VD->getType()->getAs<RecordType>()) {
+ if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+ if (!RD->hasTrivialConstructor() || !RD->hasTrivialDestructor())
+ return true;
+ }
+ }
+
+ // In C++, this doesn't need to be seen if it is marked "extern".
+ if (Context.getLangOptions().CPlusPlus && !VD->getInit() &&
+ (VD->getStorageClass() == VarDecl::Extern ||
+ VD->isExternC()))
+ return false;
+
+ // In C, this doesn't need to be seen unless it is a definition.
+ if (!Context.getLangOptions().CPlusPlus && !VD->getInit())
+ return false;
+
+ // Otherwise, this is required unless it is static.
+ return VD->getStorageClass() != VarDecl::Static;
+ }
}
void PCHWriter::WriteDecl(ASTContext &Context, Decl *D) {
diff --git a/test/PCH/cxx-required-decls.cpp b/test/PCH/cxx-required-decls.cpp
index 818958ea1e..0e39ce36fe 100644
--- a/test/PCH/cxx-required-decls.cpp
+++ b/test/PCH/cxx-required-decls.cpp
@@ -6,4 +6,3 @@
// RUN: %clang_cc1 -include-pch %t %s -emit-llvm -o - | FileCheck %s
// CHECK: @_ZL5globS = internal global %struct.S zeroinitializer
-// CHECK: @_ZL3bar = internal global i32 0, align 4
diff --git a/test/PCH/cxx-required-decls.h b/test/PCH/cxx-required-decls.h
index df28ad6c2f..f4fa79e4ee 100644
--- a/test/PCH/cxx-required-decls.h
+++ b/test/PCH/cxx-required-decls.h
@@ -5,6 +5,3 @@ struct S {
};
static S globS;
-
-extern int ext_foo;
-static int bar = ++ext_foo;
diff --git a/tools/libclang/Makefile b/tools/libclang/Makefile
index 0f362cd26e..253ea38c7b 100644
--- a/tools/libclang/Makefile
+++ b/tools/libclang/Makefile
@@ -17,7 +17,7 @@ SHARED_LIBRARY = 1
LINK_COMPONENTS := bitreader mc core
USEDLIBS = clangFrontend.a clangDriver.a clangSema.a \
- clangAnalysis.a clangAST.a clangCodeGen.a clangParse.a clangLex.a clangBasic.a
+ clangAnalysis.a clangAST.a clangParse.a clangLex.a clangBasic.a
include $(CLANG_LEVEL)/Makefile