Index: src/PNaClTranslator.cpp |
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp |
index 46bd26159e906f80af701e7e97807c723cd0c71f..a3cc45e62b13cdb70a304a51116be870a15a7d34 100644 |
--- a/src/PNaClTranslator.cpp |
+++ b/src/PNaClTranslator.cpp |
@@ -163,6 +163,7 @@ public: |
NaClBitstreamCursor &Cursor, Ice::ErrorCode &ErrorStatus) |
: NaClBitcodeParser(Cursor), Translator(Translator), Header(Header), |
ErrorStatus(ErrorStatus), NumErrors(0), NextDefiningFunctionID(0), |
+ VariableDeclarations(new Ice::VariableDeclarationList()), |
BlockParser(nullptr), StubbedConstCallValue(nullptr) {} |
~TopLevelParser() override {} |
@@ -251,71 +252,27 @@ public: |
return reportGetFunctionByIDError(ID); |
} |
- /// Returns the list of function declarations. |
- const FunctionDeclarationListType &getFunctionDeclarationList() const { |
- return FunctionDeclarationList; |
+ /// Returns the constant associated with the given global value ID. |
+ Ice::Constant *getGlobalConstantByID(unsigned ID) { |
+ assert(ID < ValueIDConstants.size()); |
+ return ValueIDConstants[ID]; |
} |
- /// Returns the corresponding constant associated with a global declaration. |
- /// (i.e. relocatable). |
- Ice::Constant *getOrCreateGlobalConstantByID(unsigned ID) { |
- // TODO(kschimpf): Can this be built when creating global initializers? |
- Ice::Constant *C; |
- if (ID >= ValueIDConstants.size()) { |
- C = nullptr; |
- unsigned ExpectedSize = |
- FunctionDeclarationList.size() + VariableDeclarations.size(); |
- if (ID >= ExpectedSize) |
- ExpectedSize = ID; |
- ValueIDConstants.resize(ExpectedSize); |
- } else { |
- C = ValueIDConstants[ID]; |
- } |
- if (C != nullptr) |
- return C; |
+ /// Install names for all global values without names. Called after |
+ /// the global value symbol table is processed, but before any |
+ /// function blocks are processed. |
+ void installGlobalNames() { |
+ assert(VariableDeclarations.get()); |
Jim Stichnoth
2015/02/10 04:01:04
You should be able to just assert(VariableDeclarat
Karl
2015/02/10 17:19:26
Good point. Didn't realize it had a bool type conv
|
+ installGlobalVarNames(); |
+ installFunctionNames(); |
+ } |
- if (isIRGenerationDisabled()) { |
- ValueIDConstants[ID] = nullptr; |
- return nullptr; |
- } |
- |
- // If reached, no such constant exists, create one. |
- // TODO(kschimpf) Don't get addresses of intrinsic function declarations. |
- Ice::GlobalDeclaration *Decl = nullptr; |
- unsigned FcnIDSize = FunctionDeclarationList.size(); |
- bool IsUndefined = false; |
- if (ID < FcnIDSize) { |
- Decl = FunctionDeclarationList[ID]; |
- const auto Func = llvm::cast<Ice::FunctionDeclaration>(Decl); |
- IsUndefined = Func->isProto(); |
- } else if ((ID - FcnIDSize) < VariableDeclarations.size()) { |
- Decl = VariableDeclarations[ID - FcnIDSize]; |
- const auto Var = llvm::cast<Ice::VariableDeclaration>(Decl); |
- IsUndefined = !Var->hasInitializer(); |
- } |
- Ice::IceString Name; |
- bool SuppressMangling; |
- if (Decl) { |
- Name = Decl->getName(); |
- SuppressMangling = Decl->getSuppressMangling(); |
- } else { |
- std::string Buffer; |
- raw_string_ostream StrBuf(Buffer); |
- StrBuf << "Reference to global not defined: " << ID; |
- BlockError(StrBuf.str()); |
- // TODO(kschimpf) Remove error recovery once implementation complete. |
- Name = "??"; |
- SuppressMangling = false; |
- } |
- if (IsUndefined) |
- C = getTranslator().getContext()->getConstantExternSym(Name); |
- else { |
- const Ice::RelocOffsetT Offset = 0; |
- C = getTranslator().getContext()->getConstantSym(Offset, Name, |
- SuppressMangling); |
- } |
- ValueIDConstants[ID] = C; |
- return C; |
+ void createValueIDs() { |
+ assert(VariableDeclarations.get()); |
Jim Stichnoth
2015/02/10 04:01:05
assert(VariableDeclarations);
Karl
2015/02/10 17:19:26
Done.
|
+ ValueIDConstants.reserve(VariableDeclarations->size() + |
+ FunctionDeclarationList.size()); |
+ createValueIDsForFunctions(); |
+ createValueIDsForGlobalVars(); |
} |
/// Returns a defined function reference to be used in place of |
@@ -328,7 +285,7 @@ public: |
for (unsigned i = 0; i < getNumFunctionIDs(); ++i) { |
Ice::FunctionDeclaration *Func = getFunctionByID(i); |
if (!Func->isProto()) { |
- StubbedConstCallValue = getOrCreateGlobalConstantByID(i); |
+ StubbedConstCallValue = getGlobalConstantByID(i); |
return StubbedConstCallValue; |
} |
} |
@@ -342,27 +299,37 @@ public: |
/// Returns the number of global declarations (i.e. IDs) defined in |
/// the bitcode file. |
unsigned getNumGlobalIDs() const { |
- return FunctionDeclarationList.size() + VariableDeclarations.size(); |
+ if (Ice::VariableDeclarationList *Decls = VariableDeclarations.get()) { |
+ return FunctionDeclarationList.size() + Decls->size(); |
Jim Stichnoth
2015/02/10 04:01:05
if (VariableDeclarations) {
return FunctionDecla
Karl
2015/02/10 17:19:26
Done.
|
+ } else { |
+ return ValueIDConstants.size(); |
+ } |
} |
/// Creates Count global variable declarations. |
void CreateGlobalVariables(size_t Count) { |
- assert(VariableDeclarations.empty()); |
+ assert(VariableDeclarations.get()); |
Jim Stichnoth
2015/02/10 04:01:05
assert(VariableDeclarations);
Karl
2015/02/10 17:19:26
Done.
|
+ assert(VariableDeclarations->empty()); |
for (size_t i = 0; i < Count; ++i) { |
- VariableDeclarations.push_back(Ice::VariableDeclaration::create()); |
+ VariableDeclarations->push_back(Ice::VariableDeclaration::create()); |
} |
} |
/// Returns the number of global variable declarations in the |
/// bitcode file. |
Ice::SizeT getNumGlobalVariables() const { |
- return VariableDeclarations.size(); |
+ if (Ice::VariableDeclarationList *Decls = VariableDeclarations.get()) { |
+ return Decls->size(); |
Jim Stichnoth
2015/02/10 04:01:04
if (VariableDeclarations) {
return VariableDecla
Karl
2015/02/10 17:19:26
Done.
|
+ } else { |
+ return ValueIDConstants.size() - FunctionDeclarationList.size(); |
+ } |
} |
/// Returns the global variable declaration with the given index. |
Ice::VariableDeclaration *getGlobalVariableByID(unsigned Index) { |
- if (Index < VariableDeclarations.size()) |
- return VariableDeclarations[Index]; |
+ assert(VariableDeclarations.get()); |
Jim Stichnoth
2015/02/10 04:01:05
assert(VariableDeclarations);
Karl
2015/02/10 17:19:26
Done.
|
+ if (Index < VariableDeclarations->size()) |
+ return VariableDeclarations->at(Index); |
return reportGetGlobalVariableByIDError(Index); |
} |
@@ -376,9 +343,15 @@ public: |
return getGlobalVariableByID(Index - NumFunctionIds); |
} |
- /// Returns the list of parsed global variable declarations. |
- const Ice::VariableDeclarationList &getGlobalVariables() { |
- return VariableDeclarations; |
+ /// Returns the list of parsed global variable declarations. Releases |
+ /// ownership of the current list of global variables. |
+ Ice::VariableDeclarationList *getGlobalVariables() { |
Jim Stichnoth
2015/02/10 04:01:04
This would be better returning a unique_ptr. The
Karl
2015/02/10 17:19:26
I didn't know how to return a unique_ptr, which wa
|
+ // Before returning, check that ValidIDConstants has already been |
+ // build. |
+ if (Ice::VariableDeclarationList *Decls = VariableDeclarations.get()) { |
+ assert(Decls->size() <= ValueIDConstants.size()); |
Jim Stichnoth
2015/02/10 04:01:04
if (VariableDeclarations) {
assert(VariableDecla
Karl
2015/02/10 17:19:26
Done.
|
+ } |
+ return VariableDeclarations.release(); |
} |
private: |
@@ -402,7 +375,7 @@ private: |
// actually-defined function. |
size_t NextDefiningFunctionID; |
// The set of global variables. |
- Ice::VariableDeclarationList VariableDeclarations; |
+ std::unique_ptr<Ice::VariableDeclarationList> VariableDeclarations; |
// Relocatable constants associated with global declarations. |
std::vector<Ice::Constant *> ValueIDConstants; |
// Error recovery value to use when getFuncSigTypeByID fails. |
@@ -432,6 +405,91 @@ private: |
return nullptr; |
} |
+ // Gives Decl a name if it doesn't already have one. Prefix and |
+ // NameIndex is used to generate the name. NameIndex is |
+ // automatically incremented if a new new is created. Context is |
+ // literal text describing the type of name being created. |
+ void installDeclarationName(// Ice::Translator &Trans, |
Jim Stichnoth
2015/02/10 04:01:05
Remove comment in arglist? Same for the two calls
Karl
2015/02/10 17:19:26
Done.
|
+ Ice::GlobalDeclaration *Decl, |
+ const Ice::IceString &Prefix, const char *Context, |
Jim Stichnoth
2015/02/10 04:01:04
Bikeshedding. Maybe rename the Context arg, since
Karl
2015/02/10 17:19:26
Done.
|
+ uint32_t &NameIndex) { |
+ if (!Decl->hasName()) { |
+ Decl->setName(Translator.createUnnamedName(Prefix, NameIndex)); |
+ ++NameIndex; |
+ } else { |
+ Translator.checkIfUnnamedNameSafe(Decl->getName(), Context, Prefix); |
+ } |
+ } |
+ |
+ // Installs names for global variables without names. |
+ void installGlobalVarNames() { |
+ assert(VariableDeclarations.get()); |
Jim Stichnoth
2015/02/10 04:01:04
assert(VariableDeclarations);
Karl
2015/02/10 17:19:26
Done.
|
+ const Ice::IceString &GlobalPrefix = |
+ getTranslator().getFlags().getDefaultGlobalPrefix(); |
+ if (!GlobalPrefix.empty()) { |
+ // Ice::Translator &Trans = getTranslator(); |
Jim Stichnoth
2015/02/10 04:01:05
remove?
Karl
2015/02/10 17:19:26
Done.
|
+ uint32_t NameIndex = 0; |
+ for (Ice::VariableDeclaration *Var : *VariableDeclarations) { |
+ installDeclarationName(/*Trans,*/ Var, GlobalPrefix, "global", NameIndex); |
+ } |
+ } |
+ } |
+ |
+ // Installs names for functions without names. |
+ void installFunctionNames() { |
+ const Ice::IceString &FunctionPrefix = |
+ getTranslator().getFlags().getDefaultFunctionPrefix(); |
+ if (!FunctionPrefix.empty()) { |
+ // Ice::Translator &Trans = getTranslator(); |
Jim Stichnoth
2015/02/10 04:01:04
remove?
Karl
2015/02/10 17:19:26
Done.
|
+ uint32_t NameIndex = 0; |
+ for (Ice::FunctionDeclaration *Func : FunctionDeclarationList) { |
+ installDeclarationName(/*Trans,*/ Func, FunctionPrefix, "function", |
+ NameIndex); |
+ } |
+ } |
+ } |
+ |
+ // Builds a constant symbol named Name, suppressing name mangling if |
+ // SuppressMangling. IsExternal is true iff the symbol is external. |
+ Ice::Constant *getConstantSym(const Ice::IceString &Name, |
+ bool SuppressMangling, bool IsExternal) { |
+ if (IsExternal) { |
+ return getTranslator().getContext()->getConstantExternSym(Name); |
+ } else { |
+ const Ice::RelocOffsetT Offset = 0; |
+ return getTranslator().getContext()->getConstantSym(Offset, Name, |
+ SuppressMangling); |
+ } |
+ } |
+ |
+ // Converts function declarations into constant value IDs. |
+ void createValueIDsForFunctions() { |
+ size_t NumFunctions = FunctionDeclarationList.size(); |
+ for (size_t i = 0; i < NumFunctions; ++i) { |
Jim Stichnoth
2015/02/10 04:01:05
Can you use a range-based for loop?
Karl
2015/02/10 17:19:26
I didn't use a range-based loop, since I needed in
|
+ Ice::Constant *C = nullptr; |
+ if (!isIRGenerationDisabled()) { |
+ Ice::FunctionDeclaration *Func = FunctionDeclarationList[i]; |
+ C = getConstantSym(Func->getName(), Func->getSuppressMangling(), |
+ Func->isProto()); |
jvoung (off chromium)
2015/02/10 18:24:58
Thanks for simplifying the IsExternal a bit.
|
+ } |
+ ValueIDConstants.push_back(C); |
+ } |
+ } |
+ |
+ // Converts global variable declarations into constant value IDs. |
+ void createValueIDsForGlobalVars() { |
+ size_t NumGlobalVars = VariableDeclarations->size(); |
+ for (size_t i = 0; i < NumGlobalVars; ++i) { |
Jim Stichnoth
2015/02/10 04:01:05
Range-based for loop?
Karl
2015/02/10 17:19:26
Done.
|
+ Ice::Constant *C = nullptr; |
+ if (!isIRGenerationDisabled()) { |
+ Ice::VariableDeclaration *Decl = VariableDeclarations->at(i); |
+ C = getConstantSym(Decl->getName(), Decl->getSuppressMangling(), |
+ !Decl->hasInitializer()); |
+ } |
+ ValueIDConstants.push_back(C); |
+ } |
+ } |
+ |
// Reports that type ID is undefined, or not of the WantedType. |
void reportBadTypeIDAs(unsigned ID, const ExtendedType *Ty, |
ExtendedType::TypeKind WantedType); |
@@ -494,11 +552,11 @@ TopLevelParser::reportGetGlobalVariableByIDError(unsigned Index) { |
raw_string_ostream StrBuf(Buffer); |
StrBuf << "Global index " << Index |
<< " not allowed. Out of range. Must be less than " |
- << VariableDeclarations.size(); |
+ << VariableDeclarations->size(); |
BlockError(StrBuf.str()); |
// TODO(kschimpf) Remove error recovery once implementation complete. |
- if (!VariableDeclarations.empty()) |
- return VariableDeclarations[0]; |
+ if (!VariableDeclarations->empty()) |
+ return VariableDeclarations->at(0); |
report_fatal_error("Unable to continue"); |
} |
@@ -1160,7 +1218,7 @@ public: |
// Returns the value referenced by the given value Index. |
Ice::Operand *getOperand(uint32_t Index) { |
if (Index < CachedNumGlobalValueIDs) { |
- return Context->getOrCreateGlobalConstantByID(Index); |
+ return Context->getGlobalConstantByID(Index); |
} |
uint32_t LocalIndex = Index - CachedNumGlobalValueIDs; |
if (LocalIndex >= LocalOperands.size()) { |
@@ -2808,41 +2866,15 @@ private: |
// the first call will do the installation. |
void InstallGlobalNamesAndGlobalVarInitializers() { |
if (!GlobalDeclarationNamesAndInitializersInstalled) { |
- Ice::Translator &Trans = getTranslator(); |
- const Ice::IceString &GlobalPrefix = getFlags().getDefaultGlobalPrefix(); |
- if (!GlobalPrefix.empty()) { |
- uint32_t NameIndex = 0; |
- for (Ice::VariableDeclaration *Var : Context->getGlobalVariables()) { |
- installDeclarationName(Trans, Var, GlobalPrefix, "global", NameIndex); |
- } |
- } |
- const Ice::IceString &FunctionPrefix = |
- getFlags().getDefaultFunctionPrefix(); |
- if (!FunctionPrefix.empty()) { |
- uint32_t NameIndex = 0; |
- for (Ice::FunctionDeclaration *Func : |
- Context->getFunctionDeclarationList()) { |
- installDeclarationName(Trans, Func, FunctionPrefix, "function", |
- NameIndex); |
- } |
- } |
- getTranslator().lowerGlobals(Context->getGlobalVariables()); |
+ Context->installGlobalNames(); |
+ Context->createValueIDs(); |
+ std::unique_ptr<Ice::VariableDeclarationList> DeclsPtr( |
+ Context->getGlobalVariables()); |
Jim Stichnoth
2015/02/10 04:01:04
With the suggested change to the getGlobalVariable
Karl
2015/02/10 17:19:26
Done.
|
+ const Ice::VariableDeclarationList &Decls = *DeclsPtr; |
+ getTranslator().lowerGlobals(Decls); |
GlobalDeclarationNamesAndInitializersInstalled = true; |
} |
} |
- |
- void installDeclarationName(Ice::Translator &Trans, |
- Ice::GlobalDeclaration *Decl, |
- const Ice::IceString &Prefix, const char *Context, |
- uint32_t &NameIndex) { |
- if (!Decl->hasName()) { |
- Decl->setName(Trans.createUnnamedName(Prefix, NameIndex)); |
- ++NameIndex; |
- } else { |
- Trans.checkIfUnnamedNameSafe(Decl->getName(), Context, Prefix); |
- } |
- } |
- |
bool ParseBlock(unsigned BlockID) override; |
void ExitBlock() override { InstallGlobalNamesAndGlobalVarInitializers(); } |