aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AsmParser/LLLexer.h4
-rw-r--r--lib/AsmParser/LLParser.cpp575
-rw-r--r--lib/AsmParser/LLParser.h87
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp390
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.h10
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp113
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.cpp114
-rw-r--r--lib/Bitcode/Writer/ValueEnumerator.h3
-rw-r--r--lib/CodeGen/ShadowStackGC.cpp49
-rw-r--r--lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp1
-rw-r--r--lib/Linker/LinkModules.cpp1816
-rw-r--r--lib/Target/CBackend/CBackend.cpp217
-rw-r--r--lib/Target/CppBackend/CPPBackend.cpp88
-rw-r--r--lib/Target/TargetData.cpp51
-rw-r--r--lib/Transforms/IPO/CMakeLists.txt1
-rw-r--r--lib/Transforms/IPO/DeadTypeElimination.cpp112
-rw-r--r--lib/Transforms/IPO/IPO.cpp5
-rw-r--r--lib/Transforms/IPO/MergeFunctions.cpp1
-rw-r--r--lib/Transforms/IPO/StripSymbols.cpp24
-rw-r--r--lib/Transforms/Utils/CloneModule.cpp24
-rw-r--r--lib/Transforms/Utils/LowerInvoke.cpp22
-rw-r--r--lib/Transforms/Utils/ValueMapper.cpp107
-rw-r--r--lib/VMCore/AsmWriter.cpp441
-rw-r--r--lib/VMCore/CMakeLists.txt1
-rw-r--r--lib/VMCore/ConstantFold.cpp2
-rw-r--r--lib/VMCore/Constants.cpp56
-rw-r--r--lib/VMCore/ConstantsContext.h142
-rw-r--r--lib/VMCore/Core.cpp49
-rw-r--r--lib/VMCore/Function.cpp6
-rw-r--r--lib/VMCore/Globals.cpp1
-rw-r--r--lib/VMCore/InlineAsm.cpp2
-rw-r--r--lib/VMCore/Instructions.cpp66
-rw-r--r--lib/VMCore/LLVMContextImpl.cpp18
-rw-r--r--lib/VMCore/LLVMContextImpl.h47
-rw-r--r--lib/VMCore/Metadata.cpp1
-rw-r--r--lib/VMCore/Module.cpp178
-rw-r--r--lib/VMCore/Type.cpp1205
-rw-r--r--lib/VMCore/TypeSymbolTable.cpp168
-rw-r--r--lib/VMCore/TypesContext.h426
-rw-r--r--lib/VMCore/Value.cpp15
-rw-r--r--lib/VMCore/Verifier.cpp130
41 files changed, 2365 insertions, 4403 deletions
diff --git a/lib/AsmParser/LLLexer.h b/lib/AsmParser/LLLexer.h
index 4fe705e1a5..33b9135723 100644
--- a/lib/AsmParser/LLLexer.h
+++ b/lib/AsmParser/LLLexer.h
@@ -38,7 +38,7 @@ namespace llvm {
lltok::Kind CurKind;
std::string StrVal;
unsigned UIntVal;
- const Type *TyVal;
+ Type *TyVal;
APFloat APFloatVal;
APSInt APSIntVal;
@@ -56,7 +56,7 @@ namespace llvm {
LocTy getLoc() const { return SMLoc::getFromPointer(TokStart); }
lltok::Kind getKind() const { return CurKind; }
const std::string &getStrVal() const { return StrVal; }
- const Type *getTyVal() const { return TyVal; }
+ Type *getTyVal() const { return TyVal; }
unsigned getUIntVal() const { return UIntVal; }
const APSInt &getAPSIntVal() const { return APSIntVal; }
const APFloat &getAPFloatVal() const { return APFloatVal; }
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index d9858514be..881b3e943b 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -89,15 +89,16 @@ bool LLParser::ValidateEndOfModule() {
ForwardRefBlockAddresses.erase(ForwardRefBlockAddresses.begin());
}
-
- if (!ForwardRefTypes.empty())
- return Error(ForwardRefTypes.begin()->second.second,
- "use of undefined type named '" +
- ForwardRefTypes.begin()->first + "'");
- if (!ForwardRefTypeIDs.empty())
- return Error(ForwardRefTypeIDs.begin()->second.second,
- "use of undefined type '%" +
- Twine(ForwardRefTypeIDs.begin()->first) + "'");
+ for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i)
+ if (NumberedTypes[i].second.isValid())
+ return Error(NumberedTypes[i].second,
+ "use of undefined type '%" + Twine(i) + "'");
+
+ for (StringMap<std::pair<Type*, LocTy> >::iterator I =
+ NamedTypes.begin(), E = NamedTypes.end(); I != E; ++I)
+ if (I->second.second.isValid())
+ return Error(I->second.second,
+ "use of undefined type named '" + I->getKey() + "'");
if (!ForwardRefVals.empty())
return Error(ForwardRefVals.begin()->second.second,
@@ -293,36 +294,32 @@ bool LLParser::ParseDepLibs() {
/// ::= LocalVarID '=' 'type' type
bool LLParser::ParseUnnamedType() {
LocTy TypeLoc = Lex.getLoc();
- unsigned TypeID = NumberedTypes.size();
- if (Lex.getUIntVal() != TypeID)
- return Error(Lex.getLoc(), "type expected to be numbered '%" +
- Twine(TypeID) + "'");
+ unsigned TypeID = Lex.getUIntVal();
Lex.Lex(); // eat LocalVarID;
if (ParseToken(lltok::equal, "expected '=' after name") ||
ParseToken(lltok::kw_type, "expected 'type' after '='"))
return true;
- PATypeHolder Ty(Type::getVoidTy(Context));
- if (ParseType(Ty)) return true;
-
- // See if this type was previously referenced.
- std::map<unsigned, std::pair<PATypeHolder, LocTy> >::iterator
- FI = ForwardRefTypeIDs.find(TypeID);
- if (FI != ForwardRefTypeIDs.end()) {
- if (FI->second.first.get() == Ty)
- return Error(TypeLoc, "self referential type is invalid");
-
- cast<DerivedType>(FI->second.first.get())->refineAbstractTypeTo(Ty);
- Ty = FI->second.first.get();
- ForwardRefTypeIDs.erase(FI);
+ if (TypeID >= NumberedTypes.size())
+ NumberedTypes.resize(TypeID+1);
+
+ Type *Result = 0;
+ if (ParseStructDefinition(TypeLoc, "",
+ NumberedTypes[TypeID], Result)) return true;
+
+ if (!isa<StructType>(Result)) {
+ std::pair<Type*, LocTy> &Entry = NumberedTypes[TypeID];
+ if (Entry.first)
+ return Error(TypeLoc, "non-struct types may not be recursive");
+ Entry.first = Result;
+ Entry.second = SMLoc();
}
- NumberedTypes.push_back(Ty);
-
return false;
}
+
/// toplevelentity
/// ::= LocalVar '=' 'type' type
bool LLParser::ParseNamedType() {
@@ -330,37 +327,23 @@ bool LLParser::ParseNamedType() {
LocTy NameLoc = Lex.getLoc();
Lex.Lex(); // eat LocalVar.
- PATypeHolder Ty(Type::getVoidTy(Context));
-
if (ParseToken(lltok::equal, "expected '=' after name") ||
- ParseToken(lltok::kw_type, "expected 'type' after name") ||
- ParseType(Ty))
+ ParseToken(lltok::kw_type, "expected 'type' after name"))
return true;
-
- // Set the type name, checking for conflicts as we do so.
- bool AlreadyExists = M->addTypeName(Name, Ty);
- if (!AlreadyExists) return false;
-
- // See if this type is a forward reference. We need to eagerly resolve
- // types to allow recursive type redefinitions below.
- std::map<std::string, std::pair<PATypeHolder, LocTy> >::iterator
- FI = ForwardRefTypes.find(Name);
- if (FI != ForwardRefTypes.end()) {
- if (FI->second.first.get() == Ty)
- return Error(NameLoc, "self referential type is invalid");
-
- cast<DerivedType>(FI->second.first.get())->refineAbstractTypeTo(Ty);
- Ty = FI->second.first.get();
- ForwardRefTypes.erase(FI);
- return false;
+
+ Type *Result = 0;
+ if (ParseStructDefinition(NameLoc, Name,
+ NamedTypes[Name], Result)) return true;
+
+ if (!isa<StructType>(Result)) {
+ std::pair<Type*, LocTy> &Entry = NamedTypes[Name];
+ if (Entry.first)
+ return Error(NameLoc, "non-struct types may not be recursive");
+ Entry.first = Result;
+ Entry.second = SMLoc();
}
-
- // Inserting a name that is already defined, get the existing name.
- assert(M->getTypeByName(Name) && "Conflict but no matching type?!");
-
- // Otherwise, this is an attempt to redefine a type, report the error.
- return Error(NameLoc, "redefinition of type named '" + Name + "' of type '" +
- getTypeString(Ty) + "'");
+
+ return false;
}
@@ -536,7 +519,7 @@ bool LLParser::ParseStandaloneMetadata() {
unsigned MetadataID = 0;
LocTy TyLoc;
- PATypeHolder Ty(Type::getVoidTy(Context));
+ Type *Ty = 0;
SmallVector<Value *, 16> Elts;
if (ParseUInt32(MetadataID) ||
ParseToken(lltok::equal, "expected '=' here") ||
@@ -668,7 +651,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
LocTy UnnamedAddrLoc;
LocTy TyLoc;
- PATypeHolder Ty(Type::getVoidTy(Context));
+ Type *Ty = 0;
if (ParseOptionalToken(lltok::kw_thread_local, ThreadLocal) ||
ParseOptionalAddrSpace(AddrSpace) ||
ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,
@@ -792,18 +775,11 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, const Type *Ty,
// Otherwise, create a new forward reference for this value and remember it.
GlobalValue *FwdVal;
- if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType())) {
- // Function types can return opaque but functions can't.
- if (FT->getReturnType()->isOpaqueTy()) {
- Error(Loc, "function may not return opaque type");
- return 0;
- }
-
+ if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType()))
FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M);
- } else {
+ else
FwdVal = new GlobalVariable(*M, PTy->getElementType(), false,
GlobalValue::ExternalWeakLinkage, 0, Name);
- }
ForwardRefVals[Name] = std::make_pair(FwdVal, Loc);
return FwdVal;
@@ -837,17 +813,11 @@ GlobalValue *LLParser::GetGlobalVal(unsigned ID, const Type *Ty, LocTy Loc) {
// Otherwise, create a new forward reference for this value and remember it.
GlobalValue *FwdVal;
- if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType())) {
- // Function types can return opaque but functions can't.
- if (FT->getReturnType()->isOpaqueTy()) {
- Error(Loc, "function may not return opaque type");
- return 0;
- }
+ if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType()))
FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, "", M);
- } else {
+ else
FwdVal = new GlobalVariable(*M, PTy->getElementType(), false,
GlobalValue::ExternalWeakLinkage, 0, "");
- }
ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc);
return FwdVal;
@@ -1228,165 +1198,68 @@ bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices,
// Type Parsing.
//===----------------------------------------------------------------------===//
-/// ParseType - Parse and resolve a full type.
-bool LLParser::ParseType(PATypeHolder &Result, bool AllowVoid) {
- LocTy TypeLoc = Lex.getLoc();
- if (ParseTypeRec(Result)) return true;
-
- // Verify no unresolved uprefs.
- if (!UpRefs.empty())
- return Error(UpRefs.back().Loc, "invalid unresolved type up reference");
-
- if (!AllowVoid && Result.get()->isVoidTy())
- return Error(TypeLoc, "void type only allowed for function results");
-
- return false;
-}
-
-/// HandleUpRefs - Every time we finish a new layer of types, this function is
-/// called. It loops through the UpRefs vector, which is a list of the
-/// currently active types. For each type, if the up-reference is contained in
-/// the newly completed type, we decrement the level count. When the level
-/// count reaches zero, the up-referenced type is the type that is passed in:
-/// thus we can complete the cycle.
-///
-PATypeHolder LLParser::HandleUpRefs(const Type *ty) {
- // If Ty isn't abstract, or if there are no up-references in it, then there is
- // nothing to resolve here.
- if (!ty->isAbstract() || UpRefs.empty()) return ty;
-
- PATypeHolder Ty(ty);
-#if 0
- dbgs() << "Type '" << *Ty
- << "' newly formed. Resolving upreferences.\n"
- << UpRefs.size() << " upreferences active!\n";
-#endif
-
- // If we find any resolvable upreferences (i.e., those whose NestingLevel goes
- // to zero), we resolve them all together before we resolve them to Ty. At
- // the end of the loop, if there is anything to resolve to Ty, it will be in
- // this variable.
- OpaqueType *TypeToResolve = 0;
-
- for (unsigned i = 0; i != UpRefs.size(); ++i) {
- // Determine if 'Ty' directly contains this up-references 'LastContainedTy'.
- bool ContainsType =
- std::find(Ty->subtype_begin(), Ty->subtype_end(),
- UpRefs[i].LastContainedTy) != Ty->subtype_end();
-
-#if 0
- dbgs() << " UR#" << i << " - TypeContains(" << *Ty << ", "
- << *UpRefs[i].LastContainedTy << ") = "
- << (ContainsType ? "true" : "false")
- << " level=" << UpRefs[i].NestingLevel << "\n";
-#endif
- if (!ContainsType)
- continue;
-
- // Decrement level of upreference
- unsigned Level = --UpRefs[i].NestingLevel;
- UpRefs[i].LastContainedTy = Ty;
-
- // If the Up-reference has a non-zero level, it shouldn't be resolved yet.
- if (Level != 0)
- continue;
-
-#if 0
- dbgs() << " * Resolving upreference for " << UpRefs[i].UpRefTy << "\n";
-#endif
- if (!TypeToResolve)
- TypeToResolve = UpRefs[i].UpRefTy;
- else
- UpRefs[i].UpRefTy->refineAbstractTypeTo(TypeToResolve);
- UpRefs.erase(UpRefs.begin()+i); // Remove from upreference list.
- --i; // Do not skip the next element.
- }
-
- if (TypeToResolve)
- TypeToResolve->refineAbstractTypeTo(Ty);
-
- return Ty;
-}
-
-
-/// ParseTypeRec - The recursive function used to process the internal
-/// implementation details of types.
-bool LLParser::ParseTypeRec(PATypeHolder &Result) {
+/// ParseType - Parse a type.
+bool LLParser::ParseType(Type *&Result, bool AllowVoid) {
+ SMLoc TypeLoc = Lex.getLoc();
switch (Lex.getKind()) {
default:
return TokError("expected type");
case lltok::Type:
- // TypeRec ::= 'float' | 'void' (etc)
+ // Type ::= 'float' | 'void' (etc)
Result = Lex.getTyVal();
Lex.Lex();
break;
- case lltok::kw_opaque:
- // TypeRec ::= 'opaque'
- Result = OpaqueType::get(Context);
- Lex.Lex();
- break;
case lltok::lbrace:
- // TypeRec ::= '{' ... '}'
- if (ParseStructType(Result, false))
+ // Type ::= StructType
+ if (ParseAnonStructType(Result, false))
return true;
break;
case lltok::lsquare:
- // TypeRec ::= '[' ... ']'
+ // Type ::= '[' ... ']'
Lex.Lex(); // eat the lsquare.
if (ParseArrayVectorType(Result, false))
return true;
break;
case lltok::less: // Either vector or packed struct.
- // TypeRec ::= '<' ... '>'
+ // Type ::= '<' ... '>'
Lex.Lex();
if (Lex.getKind() == lltok::lbrace) {
- if (ParseStructType(Result, true) ||
+ if (ParseAnonStructType(Result, true) ||
ParseToken(lltok::greater, "expected '>' at end of packed struct"))
return true;
} else if (ParseArrayVectorType(Result, true))
return true;
break;
- case lltok::LocalVar:
- // TypeRec ::= %foo
- if (const Type *T = M->getTypeByName(Lex.getStrVal())) {
- Result = T;
- } else {
- Result = OpaqueType::get(Context);
- ForwardRefTypes.insert(std::make_pair(Lex.getStrVal(),
- std::make_pair(Result,
- Lex.getLoc())));
- M->addTypeName(Lex.getStrVal(), Result.get());
+ case lltok::LocalVar: {
+ // Type ::= %foo
+ std::pair<Type*, LocTy> &Entry = NamedTypes[Lex.getStrVal()];
+
+ // If the type hasn't been defined yet, create a forward definition and
+ // remember where that forward def'n was seen (in case it never is defined).
+ if (Entry.first == 0) {
+ Entry.first = StructType::createNamed(Context, Lex.getStrVal());
+ Entry.second = Lex.getLoc();
}
+ Result = Entry.first;
Lex.Lex();
break;
+ }
- case lltok::LocalVarID:
- // TypeRec ::= %4
- if (Lex.getUIntVal() < NumberedTypes.size())
- Result = NumberedTypes[Lex.getUIntVal()];
- else {
- std::map<unsigned, std::pair<PATypeHolder, LocTy> >::iterator
- I = ForwardRefTypeIDs.find(Lex.getUIntVal());
- if (I != ForwardRefTypeIDs.end())
- Result = I->second.first;
- else {
- Result = OpaqueType::get(Context);
- ForwardRefTypeIDs.insert(std::make_pair(Lex.getUIntVal(),
- std::make_pair(Result,
- Lex.getLoc())));
- }
+ case lltok::LocalVarID: {
+ // Type ::= %4
+ if (Lex.getUIntVal() >= NumberedTypes.size())
+ NumberedTypes.resize(Lex.getUIntVal()+1);
+ std::pair<Type*, LocTy> &Entry = NumberedTypes[Lex.getUIntVal()];
+
+ // If the type hasn't been defined yet, create a forward definition and
+ // remember where that forward def'n was seen (in case it never is defined).
+ if (Entry.first == 0) {
+ Entry.first = StructType::createNamed(Context, "");
+ Entry.second = Lex.getLoc();
}
+ Result = Entry.first;
Lex.Lex();
break;
- case lltok::backslash: {
- // TypeRec ::= '\' 4
- Lex.Lex();
- unsigned Val;
- if (ParseUInt32(Val)) return true;
- OpaqueType *OT = OpaqueType::get(Context); //Use temporary placeholder.
- UpRefs.push_back(UpRefRecord(Lex.getLoc(), Val, OT));
- Result = OT;
- break;
}
}
@@ -1394,34 +1267,37 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) {
while (1) {
switch (Lex.getKind()) {
// End of type.
- default: return false;
+ default:
+ if (!AllowVoid && Result->isVoidTy())
+ return Error(TypeLoc, "void type only allowed for function results");
+ return false;
- // TypeRec ::= TypeRec '*'
+ // Type ::= Type '*'
case lltok::star:
- if (Result.get()->isLabelTy())
+ if (Result->isLabelTy())
return TokError("basic block pointers are invalid");
- if (Result.get()->isVoidTy())
- return TokError("pointers to void are invalid; use i8* instead");
- if (!PointerType::isValidElementType(Result.get()))
+ if (Result->isVoidTy())
+ return TokError("pointers to void are invalid - use i8* instead");
+ if (!PointerType::isValidElementType(Result))
return TokError("pointer to this type is invalid");
- Result = HandleUpRefs(PointerType::getUnqual(Result.get()));
+ Result = PointerType::getUnqual(Result);
Lex.Lex();
break;
- // TypeRec ::= TypeRec 'addrspace' '(' uint32 ')' '*'
+ // Type ::= Type 'addrspace' '(' uint32 ')' '*'
case lltok::kw_addrspace: {
- if (Result.get()->isLabelTy())
+ if (Result->isLabelTy())
return TokError("basic block pointers are invalid");
- if (Result.get()->isVoidTy())
+ if (Result->isVoidTy())
return TokError("pointers to void are invalid; use i8* instead");
- if (!PointerType::isValidElementType(Result.get()))
+ if (!PointerType::isValidElementType(Result))
return TokError("pointer to this type is invalid");
unsigned AddrSpace;
if (ParseOptionalAddrSpace(AddrSpace) ||
ParseToken(lltok::star, "expected '*' in address space"))
return true;
- Result = HandleUpRefs(PointerType::get(Result.get(), AddrSpace));
+ Result = PointerType::get(Result, AddrSpace);
break;
}
@@ -1452,7 +1328,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
// Parse the argument.
LocTy ArgLoc;
- PATypeHolder ArgTy(Type::getVoidTy(Context));
+ Type *ArgTy = 0;
unsigned ArgAttrs1 = Attribute::None;
unsigned ArgAttrs2 = Attribute::None;
Value *V;
@@ -1472,7 +1348,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
/// ParseArgumentList - Parse the argument list for a function type or function
-/// prototype. If 'inType' is true then we are parsing a FunctionType.
+/// prototype.
/// ::= '(' ArgTypeListI ')'
/// ArgTypeListI
/// ::= /*empty*/
@@ -1480,8 +1356,8 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
/// ::= ArgTypeList ',' '...'
/// ::= ArgType (',' ArgType)*
///
-bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
- bool &isVarArg, bool inType) {
+bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
+ bool &isVarArg){
isVarArg = false;
assert(Lex.getKind() == lltok::lparen);
Lex.Lex(); // eat the (.
@@ -1493,14 +1369,11 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
Lex.Lex();
} else {
LocTy TypeLoc = Lex.getLoc();
- PATypeHolder ArgTy(Type::getVoidTy(Context));
+ Type *ArgTy = 0;
unsigned Attrs;
std::string Name;
- // If we're parsing a type, use ParseTypeRec, because we allow recursive
- // types (such as a function returning a pointer to itself). If parsing a
- // function prototype, we require fully resolved types.
- if ((inType ? ParseTypeRec(ArgTy) : ParseType(ArgTy)) ||
+ if (ParseType(ArgTy) ||
ParseOptionalAttrs(Attrs, 0)) return true;
if (ArgTy->isVoidTy())
@@ -1525,8 +1398,7 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
// Otherwise must be an argument type.
TypeLoc = Lex.getLoc();
- if ((inType ? ParseTypeRec(ArgTy) : ParseType(ArgTy)) ||
- ParseOptionalAttrs(Attrs, 0)) return true;
+ if (ParseType(ArgTy) || ParseOptionalAttrs(Attrs, 0)) return true;
if (ArgTy->isVoidTy())
return Error(TypeLoc, "argument can not have void type");
@@ -1538,7 +1410,7 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
Name = "";
}
- if (!ArgTy->isFirstClassType() && !ArgTy->isOpaqueTy())
+ if (!ArgTy->isFirstClassType())
return Error(TypeLoc, "invalid type for function argument");
ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name));
@@ -1550,15 +1422,15 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
/// ParseFunctionType
/// ::= Type ArgumentList OptionalAttrs
-bool LLParser::ParseFunctionType(PATypeHolder &Result) {
+bool LLParser::ParseFunctionType(Type *&Result) {
assert(Lex.getKind() == lltok::lparen);
if (!FunctionType::isValidReturnType(Result))
return TokError("invalid function return type");
- std::vector<ArgInfo> ArgList;
+ SmallVector<ArgInfo, 8> ArgList;
bool isVarArg;
- if (ParseArgumentList(ArgList, isVarArg, true))
+ if (ParseArgumentList(ArgList, isVarArg))
return true;
// Reject names on the arguments lists.
@@ -1570,68 +1442,122 @@ bool LLParser::ParseFunctionType(PATypeHolder &Result) {
"argument attributes invalid in function type");
}
- std::vector<const Type*> ArgListTy;
+ SmallVector<const Type*, 16> ArgListTy;
for (unsigned i = 0, e = ArgList.size(); i != e; ++i)
- ArgListTy.push_back(ArgList[i].Type);
+ ArgListTy.push_back(ArgList[i].Ty);
+
+ Result = FunctionType::get(Result, ArgListTy, isVarArg);
+ return false;
+}
- Result = HandleUpRefs(FunctionType::get(Result.get(),
- ArgListTy, isVarArg));
+/// ParseAnonStructType - Parse an anonymous struct type, which is inlined into
+/// other structs.
+bool LLParser::ParseAnonStructType(Type *&Result, bool Packed) {
+ SmallVector<Type*, 8> Elts;
+ if (ParseStructBody(Elts)) return true;
+
+ Result = StructType::get(Context, Elts, Packed);
+ return false;
+}
+
+/// ParseStructDefinition - Parse a struct in a 'type' definition.
+bool LLParser::ParseStructDefinition(SMLoc TypeLoc, StringRef Name,
+ std::pair<Type*, LocTy> &Entry,
+ Type *&ResultTy) {
+ // If the type was already defined, diagnose the redefinition.
+ if (Entry.first && !Entry.second.isValid())
+ return Error(TypeLoc, "redefinition of type");
+
+ // If we have opaque, just return without filling in the definition for the
+ // struct. This counts as a definition as far as the .ll file goes.
+ if (EatIfPresent(lltok::kw_opaque)) {
+ // This type is being defined, so clear the location to indicate this.
+ Entry.second = SMLoc();
+
+ // If this type number has never been uttered, create it.
+ if (Entry.first == 0)
+ Entry.first = StructType::createNamed(Context, Name);
+ ResultTy = Entry.first;
+ return false;
+ }
+
+ // If the type starts with '<', then it is either a packed struct or a vector.
+ bool isPacked = EatIfPresent(lltok::less);
+
+ // If we don't have a struct, then we have a random type alias, which we
+ // accept for compatibility with old files. These types are not allowed to be
+ // forward referenced and not allowed to be recursive.
+ if (Lex.getKind() != lltok::lbrace) {
+ if (Entry.first)
+ return Error(TypeLoc, "forward references to non-struct type");
+
+ ResultTy = 0;
+ if (isPacked)
+ return ParseArrayVectorType(ResultTy, true);
+ return ParseType(ResultTy);
+ }
+
+ // This type is being defined, so clear the location to indicate this.
+ Entry.second = SMLoc();
+
+ // If this type number has never been uttered, create it.
+ if (Entry.first == 0)
+ Entry.first = StructType::createNamed(Context, Name);
+
+ StructType *STy = cast<StructType>(Entry.first);
+
+ SmallVector<Type*, 8> Body;
+ if (ParseStructBody(Body) ||
+ (isPacked && ParseToken(lltok::greater, "expected '>' in packed struct")))
+ return true;
+
+ STy->setBody(Body, isPacked);
+ ResultTy = STy;
return false;
}
+
/// ParseStructType: Handles packed and unpacked types. </> parsed elsewhere.
-/// TypeRec
+/// StructType
/// ::= '{' '}'
-/// ::= '{' TypeRec (',' TypeRec)* '}'
+/// ::= '{' Type (',' Type)* '}'
/// ::= '<' '{' '}' '>'
-/// ::= '<' '{' TypeRec (',' TypeRec)* '}' '>'
-bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) {
+/// ::= '<' '{' Type (',' Type)* '}' '>'
+bool LLParser::ParseStructBody(SmallVectorImpl<Type*> &Body) {
assert(Lex.getKind() == lltok::lbrace);
Lex.Lex(); // Consume the '{'
- if (EatIfPresent(lltok::rbrace)) {
- Result = StructType::get(Context, Packed);
+ // Handle the empty struct.
+ if (EatIfPresent(lltok::rbrace))
return false;
- }
- std::vector<PATypeHolder> ParamsList;
LocTy EltTyLoc = Lex.getLoc();
- if (ParseTypeRec(Result)) return true;
- ParamsList.push_back(Result);
+ Type *Ty = 0;
+ if (ParseType(Ty)) return true;
+ Body.push_back(Ty);
- if (Result->isVoidTy())
- return Error(EltTyLoc, "struct element can not have void type");