diff options
Diffstat (limited to 'lib')
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"); |