@@ -562,6 +562,30 @@ void CIRGenModule::emitGlobalDefinition(clang::GlobalDecl gd,
562562 llvm_unreachable (" Invalid argument to CIRGenModule::emitGlobalDefinition" );
563563}
564564
565+ mlir::Attribute
566+ CIRGenModule::getConstantArrayFromStringLiteral (const StringLiteral *e) {
567+ assert (!e->getType ()->isPointerType () && " Strings are always arrays" );
568+
569+ // Don't emit it as the address of the string, emit the string data itself
570+ // as an inline array.
571+ if (e->getCharByteWidth () == 1 ) {
572+ SmallString<64 > str (e->getString ());
573+
574+ // Resize the string to the right size, which is indicated by its type.
575+ const ConstantArrayType *cat =
576+ astContext.getAsConstantArrayType (e->getType ());
577+ uint64_t finalSize = cat->getZExtSize ();
578+ str.resize (finalSize);
579+
580+ mlir::Type eltTy = convertType (cat->getElementType ());
581+ return builder.getString (str, eltTy, finalSize);
582+ }
583+
584+ errorNYI (e->getSourceRange (),
585+ " getConstantArrayFromStringLiteral: wide characters" );
586+ return mlir::Attribute ();
587+ }
588+
565589static bool shouldBeInCOMDAT (CIRGenModule &cgm, const Decl &d) {
566590 assert (!cir::MissingFeatures::supportComdat ());
567591
@@ -749,6 +773,84 @@ CIRGenModule::getCIRLinkageVarDefinition(const VarDecl *vd, bool isConstant) {
749773 return getCIRLinkageForDeclarator (vd, linkage, isConstant);
750774}
751775
776+ static cir::GlobalOp generateStringLiteral (mlir::Location loc,
777+ mlir::TypedAttr c, CIRGenModule &cgm,
778+ StringRef globalName) {
779+ assert (!cir::MissingFeatures::addressSpace ());
780+
781+ // Create a global variable for this string
782+ // FIXME(cir): check for insertion point in module level.
783+ cir::GlobalOp gv =
784+ CIRGenModule::createGlobalOp (cgm, loc, globalName, c.getType ());
785+
786+ // Set up extra information and add to the module
787+ assert (!cir::MissingFeatures::opGlobalAlignment ());
788+ assert (!cir::MissingFeatures::opGlobalLinkage ());
789+ assert (!cir::MissingFeatures::opGlobalThreadLocal ());
790+ assert (!cir::MissingFeatures::opGlobalUnnamedAddr ());
791+ CIRGenModule::setInitializer (gv, c);
792+ assert (!cir::MissingFeatures::supportComdat ());
793+ assert (!cir::MissingFeatures::opGlobalDSOLocal ());
794+ return gv;
795+ }
796+
797+ // LLVM IR automatically uniques names when new llvm::GlobalVariables are
798+ // created. This is handy, for example, when creating globals for string
799+ // literals. Since we don't do that when creating cir::GlobalOp's, we need
800+ // a mechanism to generate a unique name in advance.
801+ //
802+ // For now, this mechanism is only used in cases where we know that the
803+ // name is compiler-generated, so we don't use the MLIR symbol table for
804+ // the lookup.
805+ std::string CIRGenModule::getUniqueGlobalName (const std::string &baseName) {
806+ // If this is the first time we've generated a name for this basename, use
807+ // it as is and start a counter for this base name.
808+ auto it = cgGlobalNames.find (baseName);
809+ if (it == cgGlobalNames.end ()) {
810+ cgGlobalNames[baseName] = 1 ;
811+ return baseName;
812+ }
813+
814+ std::string result =
815+ baseName + " ." + std::to_string (cgGlobalNames[baseName]++);
816+ // There should not be any symbol with this name in the module.
817+ assert (!mlir::SymbolTable::lookupSymbolIn (theModule, result));
818+ return result;
819+ }
820+
821+ // / Return a pointer to a constant array for the given string literal.
822+ cir::GlobalOp CIRGenModule::getGlobalForStringLiteral (const StringLiteral *s,
823+ StringRef name) {
824+ mlir::Attribute c = getConstantArrayFromStringLiteral (s);
825+
826+ if (getLangOpts ().WritableStrings ) {
827+ errorNYI (s->getSourceRange (),
828+ " getGlobalForStringLiteral: Writable strings" );
829+ }
830+
831+ // Mangle the string literal if that's how the ABI merges duplicate strings.
832+ // Don't do it if they are writable, since we don't want writes in one TU to
833+ // affect strings in another.
834+ if (getCXXABI ().getMangleContext ().shouldMangleStringLiteral (s) &&
835+ !getLangOpts ().WritableStrings ) {
836+ errorNYI (s->getSourceRange (),
837+ " getGlobalForStringLiteral: mangle string literals" );
838+ }
839+
840+ // Unlike LLVM IR, CIR doesn't automatically unique names for globals, so
841+ // we need to do that explicitly.
842+ std::string uniqueName = getUniqueGlobalName (name.str ());
843+ mlir::Location loc = getLoc (s->getSourceRange ());
844+ auto typedC = llvm::cast<mlir::TypedAttr>(c);
845+ assert (!cir::MissingFeatures::opGlobalAlignment ());
846+ cir::GlobalOp gv = generateStringLiteral (loc, typedC, *this , uniqueName);
847+ assert (!cir::MissingFeatures::opGlobalDSOLocal ());
848+
849+ assert (!cir::MissingFeatures::sanitizers ());
850+
851+ return gv;
852+ }
853+
752854void CIRGenModule::emitDeclContext (const DeclContext *dc) {
753855 for (Decl *decl : dc->decls ()) {
754856 // Unlike other DeclContexts, the contents of an ObjCImplDecl at TU scope
0 commit comments