[cfe-commits] r46745 - in /cfe/trunk: CodeGen/CodeGenModule.cpp CodeGen/CodeGenModule.h CodeGen/CodeGenTypes.cpp CodeGen/CodeGenTypes.h CodeGen/ModuleBuilder.cpp Driver/ASTConsumers.cpp include/clang/CodeGen/ModuleBuilder.h test/CodeGen/types.c
Chris Lattner
sabre at nondot.org
Tue Feb 5 00:06:14 PST 2008
Author: lattner
Date: Tue Feb 5 02:06:13 2008
New Revision: 46745
URL: http://llvm.org/viewvc/llvm-project?rev=46745&view=rev
Log:
rewrite some of the type refinement code to eliminate dangling pointers
simplify the code and generally make it more robust.
Added:
cfe/trunk/test/CodeGen/types.c
Modified:
cfe/trunk/CodeGen/CodeGenModule.cpp
cfe/trunk/CodeGen/CodeGenModule.h
cfe/trunk/CodeGen/CodeGenTypes.cpp
cfe/trunk/CodeGen/CodeGenTypes.h
cfe/trunk/CodeGen/ModuleBuilder.cpp
cfe/trunk/Driver/ASTConsumers.cpp
cfe/trunk/include/clang/CodeGen/ModuleBuilder.h
Modified: cfe/trunk/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenModule.cpp?rev=46745&r1=46744&r2=46745&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/CodeGen/CodeGenModule.cpp Tue Feb 5 02:06:13 2008
@@ -261,6 +261,27 @@
EmitGlobalVar(D);
}
+void CodeGenModule::EmitType(const TypeDecl *D) {
+ if (isa<TypedefDecl>(D)) {
+ // TODO: Emit debug info.
+ return;
+ }
+
+ assert(!isa<ObjCInterfaceDecl>(D) && "FIXME: ADD OBJC SUPPORT");
+
+ // This must be a tag decl.
+ const TagDecl *TD = cast<TagDecl>(D);
+
+ // Get the LLVM type for this TagDecl. If it is non-opaque or if this decl
+ // is still a forward declaration, just return.
+ QualType NewTy = Context.getTagDeclType(const_cast<TagDecl *>(TD));
+ const llvm::Type *T = Types.ConvertType(NewTy);
+ if (isa<llvm::OpaqueType>(T) && TD->isDefinition())
+ // Make sure that this type is translated.
+ Types.ForceTypeCompilation(NewTy);
+}
+
+
/// getBuiltinLibFunction
llvm::Function *CodeGenModule::getBuiltinLibFunction(unsigned BuiltinID) {
if (BuiltinID > BuiltinFunctions.size())
Modified: cfe/trunk/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenModule.h?rev=46745&r1=46744&r2=46745&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/CodeGen/CodeGenModule.h Tue Feb 5 02:06:13 2008
@@ -34,6 +34,7 @@
class Stmt;
class ValueDecl;
class VarDecl;
+ class TypeDecl;
class FileVarDecl;
struct LangOptions;
class Diagnostic;
@@ -87,6 +88,7 @@
void EmitFunction(const FunctionDecl *FD);
void EmitGlobalVar(const FileVarDecl *D);
void EmitGlobalVarDeclarator(const FileVarDecl *D);
+ void EmitType(const TypeDecl *D);
llvm::Constant *EmitGlobalInit(const Expr *E);
llvm::Constant *EmitConstantExpr(const Expr *E);
Modified: cfe/trunk/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenTypes.cpp?rev=46745&r1=46744&r2=46745&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/CodeGen/CodeGenTypes.cpp Tue Feb 5 02:06:13 2008
@@ -91,29 +91,6 @@
CGRecordLayouts.clear();
}
-/// isOpaqueTypeDefinition - Return true if LT is a llvm::OpaqueType
-/// and T is tag definition. This helper routine does not check
-/// relationship between T and LT.
-static bool isOpaqueTypeDefinition(QualType T, const llvm::Type *LT) {
- if (const PointerType* PTy = T->getAsPointerType()) {
- return
- isOpaqueTypeDefinition(PTy->getPointeeType(),
- cast<llvm::PointerType>(LT)->getElementType());
- }
- if (!isa<llvm::OpaqueType>(LT))
- return false;
-
- const clang::Type &Ty = *T.getCanonicalType();
- if (Ty.getTypeClass() == Type::Tagged) {
- const TagType &TT = cast<TagType>(Ty);
- const TagDecl *TD = TT.getDecl();
- if (TD->isDefinition())
- return true;
- }
-
- return false;
-}
-
/// ConvertType - Convert the specified type to its LLVM form.
const llvm::Type *CodeGenTypes::ConvertType(QualType T) {
// See if type is already cached.
@@ -121,7 +98,7 @@
I = TypeHolderMap.find(T.getTypePtr());
// If type is found in map and this is not a definition for a opaque
// place holder type then use it. Otherwise convert type T.
- if (I != TypeHolderMap.end() && !isOpaqueTypeDefinition(T, I->second.get()))
+ if (I != TypeHolderMap.end())
return I->second.get();
const llvm::Type *ResultType = ConvertNewType(T);
@@ -148,6 +125,31 @@
}
+/// ForceTypeCompilation - When we find the definition for a type, we require
+/// it to be recompiled, to update the lazy understanding of what it is in our
+/// maps.
+void CodeGenTypes::ForceTypeCompilation(QualType T) {
+ const TagDecl *TD = cast<TagType>(T)->getDecl();
+
+ // Remember the opaque LLVM type for this tagdecl.
+ llvm::DenseMap<const TagDecl*, llvm::PATypeHolder>::iterator TDTI =
+ TagDeclTypes.find(TD);
+ llvm::PATypeHolder OpaqueHolder = TDTI->second;
+ assert(isa<llvm::OpaqueType>(OpaqueHolder.get()) &&
+ "Forcing compilation of non-opaque type?");
+
+ // Remove it from TagDeclTypes so that it will be regenerated.
+ TagDeclTypes.erase(TDTI);
+
+ const llvm::Type *NT = ConvertNewType(T);
+
+ // If getting the type didn't itself refine it, refine it to its actual type
+ // now.
+ if (llvm::OpaqueType *OT = dyn_cast<llvm::OpaqueType>(OpaqueHolder.get()))
+ OT->refineAbstractTypeTo(NT);
+}
+
+
const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
const clang::Type &Ty = *T.getCanonicalType();
@@ -268,7 +270,6 @@
case Type::ASQual:
return ConvertType(cast<ASQualType>(Ty).getBaseType());
- break;
case Type::ObjCInterface:
assert(0 && "FIXME: add missing functionality here");
@@ -285,40 +286,36 @@
case Type::Tagged:
const TagType &TT = cast<TagType>(Ty);
const TagDecl *TD = TT.getDecl();
- llvm::Type *ResultType = TagDeclTypes[TD];
+ llvm::DenseMap<const TagDecl*, llvm::PATypeHolder>::iterator TDTI =
+ TagDeclTypes.find(TD);
// If corresponding llvm type is not a opaque struct type
// then use it.
- if (ResultType && !isOpaqueTypeDefinition(T, ResultType))
- return ResultType;
+ if (TDTI != TagDeclTypes.end() && // Don't have a type?
+ // Have a type, but it was opaque before and now we have a definition.
+ (!isa<llvm::OpaqueType>(TDTI->second.get()) || !TD->isDefinition()))
+ return TDTI->second;
+
+ llvm::Type *ResultType = 0;
if (!TD->isDefinition()) {
- ResultType = TagDeclTypes[TD] = llvm::OpaqueType::get();
+ ResultType = llvm::OpaqueType::get();
+ TagDeclTypes.insert(std::make_pair(TD, ResultType));
} else if (TD->getKind() == Decl::Enum) {
+ // Don't bother storing enums in TagDeclTypes.
return ConvertType(cast<EnumDecl>(TD)->getIntegerType());
} else if (TD->getKind() == Decl::Struct) {
const RecordDecl *RD = cast<const RecordDecl>(TD);
// If this is nested record and this RecordDecl is already under
// process then return associated OpaqueType for now.
- llvm::DenseMap<const RecordDecl *, llvm::Type *>::iterator
- OpaqueI = RecordTypesToResolve.find(RD);
- if (OpaqueI != RecordTypesToResolve.end())
- return OpaqueI->second;
-
- llvm::OpaqueType *OpaqueTy = NULL;
- if (ResultType)
- OpaqueTy = dyn_cast<llvm::OpaqueType>(ResultType);
- if (!OpaqueTy) {
- // Create new OpaqueType now for later use.
- // FIXME: This creates a lot of opaque types, most of them are not
- // needed. Reevaluate this when performance analyis finds tons of
- // opaque types.
- OpaqueTy = llvm::OpaqueType::get();
- TypeHolderMap.insert(std::make_pair(T.getTypePtr(),
- llvm::PATypeHolder(OpaqueTy)));
+ if (TDTI == TagDeclTypes.end()) {
+ // Create new OpaqueType now for later use in case this is a recursive
+ // type. This will later be refined to the actual type.
+ ResultType = llvm::OpaqueType::get();
+ TagDeclTypes.insert(std::make_pair(TD, ResultType));
+ TypeHolderMap.insert(std::make_pair(T.getTypePtr(), ResultType));
}
- RecordTypesToResolve[RD] = OpaqueTy;
// Layout fields.
RecordOrganizer RO(*this);
@@ -331,16 +328,19 @@
// Get llvm::StructType.
CGRecordLayout *RLI = new CGRecordLayout(RO.getLLVMType(),
RO.getPaddingFields());
- ResultType = TagDeclTypes[TD] = RLI->getLLVMType();
+ ResultType = RLI->getLLVMType();
+ TagDeclTypes.insert(std::make_pair(TD, ResultType));
CGRecordLayouts[TD] = RLI;
- // Refine any OpaqueType associated with this RecordDecl.
- OpaqueTy->refineAbstractTypeTo(ResultType);
- OpaqueI = RecordTypesToResolve.find(RD);
- assert (OpaqueI != RecordTypesToResolve.end()
- && "Expected RecordDecl in RecordTypesToResolve");
- RecordTypesToResolve.erase(OpaqueI);
+ // Refining away Opaque could cause ResultType to become invalidated.
+ // Keep it in a happy little type holder to handle this.
+ llvm::PATypeHolder Holder(ResultType);
+
+ // Refine the OpaqueType associated with this RecordDecl.
+ cast<llvm::OpaqueType>(TagDeclTypes.find(TD)->second.get())
+ ->refineAbstractTypeTo(ResultType);
+ ResultType = Holder.get();
} else if (TD->getKind() == Decl::Union) {
const RecordDecl *RD = cast<const RecordDecl>(TD);
// Just use the largest element of the union, breaking ties with the
@@ -355,11 +355,13 @@
// Get llvm::StructType.
CGRecordLayout *RLI = new CGRecordLayout(RO.getLLVMType(),
RO.getPaddingFields());
- ResultType = TagDeclTypes[TD] = RLI->getLLVMType();
+ ResultType = RLI->getLLVMType();
+ TagDeclTypes.insert(std::make_pair(TD, ResultType));
CGRecordLayouts[TD] = RLI;
} else {
std::vector<const llvm::Type*> Fields;
- ResultType = TagDeclTypes[TD] = llvm::StructType::get(Fields);
+ ResultType = llvm::StructType::get(Fields);
+ TagDeclTypes.insert(std::make_pair(TD, ResultType));
}
} else {
assert(0 && "FIXME: Implement tag decl kind!");
Modified: cfe/trunk/CodeGen/CodeGenTypes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenTypes.h?rev=46745&r1=46744&r2=46745&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CodeGenTypes.h (original)
+++ cfe/trunk/CodeGen/CodeGenTypes.h Tue Feb 5 02:06:13 2008
@@ -75,7 +75,7 @@
llvm::Module& TheModule;
const llvm::TargetData& TheTargetData;
- llvm::DenseMap<const TagDecl*, llvm::Type*> TagDeclTypes;
+ llvm::DenseMap<const TagDecl*, llvm::PATypeHolder> TagDeclTypes;
/// CGRecordLayouts - This maps llvm struct type with corresponding
/// record layout info.
@@ -100,11 +100,6 @@
private:
llvm::DenseMap<const FieldDecl *, BitFieldInfo> BitFields;
- /// RecordTypesToResolve - This keeps track of record types that are not
- /// yet incomplete. One llvm::OpaqueType is associated with each incomplete
- /// record.
- llvm::DenseMap<const RecordDecl *, llvm::Type *> RecordTypesToResolve;
-
/// TypeHolderMap - This map keeps cache of llvm::Types (through PATypeHolder)
/// and maps llvm::Types to corresponding clang::Type. llvm::PATypeHolder is
/// used instead of llvm::Type because it allows us to bypass potential
@@ -142,6 +137,12 @@
/// that corresponds to the field FD.
unsigned getLLVMFieldNo(const FieldDecl *FD);
+
+ /// ForceTypeCompilation - When we find the definition for a type, we require
+ /// it to be recompiled, to update the lazy understanding of what it is in our
+ /// maps.
+ void ForceTypeCompilation(QualType T);
+
public: // These are internal details of CGT that shouldn't be used externally.
void DecodeArgumentTypes(const FunctionTypeProto &FTP,
std::vector<const llvm::Type*> &ArgTys);
Modified: cfe/trunk/CodeGen/ModuleBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/ModuleBuilder.cpp?rev=46745&r1=46744&r2=46745&view=diff
==============================================================================
--- cfe/trunk/CodeGen/ModuleBuilder.cpp (original)
+++ cfe/trunk/CodeGen/ModuleBuilder.cpp Tue Feb 5 02:06:13 2008
@@ -50,6 +50,11 @@
Builder->EmitGlobalVarDeclarator(D);
}
+/// CodeGenTypeDecl - Compile a type.
+void clang::CodeGen::CodeGenTypeDecl(CodeGenModule *Builder, TypeDecl *D) {
+ Builder->EmitType(D);
+}
+
/// PrintStats - Emit statistic information to stderr.
///
Modified: cfe/trunk/Driver/ASTConsumers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTConsumers.cpp?rev=46745&r1=46744&r2=46745&view=diff
==============================================================================
--- cfe/trunk/Driver/ASTConsumers.cpp (original)
+++ cfe/trunk/Driver/ASTConsumers.cpp Tue Feb 5 02:06:13 2008
@@ -635,10 +635,7 @@
} else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
CodeGen::CodeGenLinkageSpec(Builder, LSD);
} else {
- assert(isa<TypeDecl>(D) && "Only expected type decls here");
- // don't codegen for now, eventually pass down for debug info.
- //std::cerr << "Read top-level typedef decl: '"
- // << D->getName() << "'\n";
+ CodeGen::CodeGenTypeDecl(Builder, cast<TypeDecl>(D));
}
}
};
Modified: cfe/trunk/include/clang/CodeGen/ModuleBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/ModuleBuilder.h?rev=46745&r1=46744&r2=46745&view=diff
==============================================================================
--- cfe/trunk/include/clang/CodeGen/ModuleBuilder.h (original)
+++ cfe/trunk/include/clang/CodeGen/ModuleBuilder.h Tue Feb 5 02:06:13 2008
@@ -24,6 +24,7 @@
class FunctionDecl;
class LinkageSpecDecl;
class FileVarDecl;
+ class TypeDecl;
struct LangOptions;
class Diagnostic;
@@ -44,6 +45,9 @@
/// CodeGenGlobalVar - Emit the specified global variable to LLVM.
void CodeGenGlobalVar(CodeGenModule *Builder, FileVarDecl *D);
+ /// CodeGenTypeDecl - Compile a type.
+ void CodeGenTypeDecl(CodeGenModule *Builder, TypeDecl *D);
+
/// PrintStats - Emit statistic information to stderr.
///
void PrintStats(CodeGenModule *Builder);
Added: cfe/trunk/test/CodeGen/types.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/types.c?rev=46745&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/types.c (added)
+++ cfe/trunk/test/CodeGen/types.c Tue Feb 5 02:06:13 2008
@@ -0,0 +1,16 @@
+// RUN: clang -emit-llvm %s
+
+struct FileName {
+ struct FileName *next;
+} *fnhead;
+
+
+struct ieeeExternal {
+ struct ieeeExternal *next;
+} *exthead;
+
+
+void f()
+{
+ struct ieeeExternal *exttmp = exthead;
+}
More information about the cfe-commits
mailing list